我们可以编写控制器来接收来自模型或视图模型的数组,但数组不是 ORM 友好的(如果您打算直接使用域模型来查看视图)。考虑到这一点,我们的 Controller 的 View 将在IList
; IList
是灵活的,它不受元素数量的限制,不像数组;与数组相比,IList 是 ORM 就绪的。
我们应该做的唯一调整是在视野中;HTML或者更确切地说是javascript,没有列表的概念,它只能使用数组或关联数组。承认这一限制,我们会将这些项目从List<ClassType>
对 javascript 友好的数组中发出。
最后,当我们提交时,我们友好的社区 ASP.NET MVC 将为我们处理这些事情,即它可以List<ClassType>
根据提交的 HTML/javascript 数组自动填充我们的变量,即我们不需要迭代Request.Form
,不需要手动填充,我们的代码操作的一切都是以模型/视图模型为中心的,因为它们应该是。ASP.NET MVC 程序员的生活很美好不是吗?;-)
完整代码如下:
模型:
namespace SoQna.Models
{
public class Question
{
public int QuestionId { get; set; }
public string QuestionText { get; set; }
}
public class Answer
{
public int AnswerId { get; set; }
public Question Question { get; set; }
public string AnswerText { get; set; }
}
}
视图模型:
using System.Collections.Generic;
namespace SoQna.ViewModels
{
public class QnaViewModel
{
public IList<AnswerToQuestion> Answers { get; set; }
}
public class AnswerToQuestion
{
public int ToQuestionId { get; set; }
public string QuestionText { get; set; }
public string AnswerText { get; set; }
}
}
控制器:
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace SoQna.Controllers
{
public class HomeController : Controller
{
IList<SoQna.Models.Question> _qnaRepo = new List<SoQna.Models.Question>
{
new SoQna.Models.Question { QuestionId = 1,
QuestionText =
"Why is there a proliferation of different kind of ORMs?"
},
new SoQna.Models.Question {
QuestionId = 2, QuestionText = "How are you?"
},
new SoQna.Models.Question {
QuestionId = 3, QuestionText = "Why the sky is blue?"
},
new SoQna.Models.Question {
QuestionId = 4, QuestionText = "Why is MVC the bees knees?"
},
};
public ActionResult Index()
{
var qna = new SoQna.ViewModels.QnaViewModel {
Answers = new List<SoQna.ViewModels.AnswerToQuestion>()
};
foreach (var question in _qnaRepo)
{
if (question.QuestionId == 1) continue; // subjective :-)
qna.Answers.Add(
new SoQna.ViewModels.AnswerToQuestion {
ToQuestionId = question.QuestionId,
QuestionText = question.QuestionText,
AnswerText = "Put your answer here"
}
);
}
return View(qna);
}
[HttpPost]
public ViewResult SubmitAnswers(SoQna.ViewModels.QnaViewModel a)
{
foreach (var answer in a.Answers)
{
answer.QuestionText = _qnaRepo.Single(x =>
x.QuestionId == answer.ToQuestionId).QuestionText;
}
return View(a);
}
}//HomeController
}//namespace
查看主页/索引
@model SoQna.ViewModels.QnaViewModel
@{
ViewBag.Title = "Index";
}
<h2>Hahah</h2>
@using (Html.BeginForm("SubmitAnswers", "Home"))
{
int i = 0;
foreach (var answer in Model.Answers)
{
@: Question #@(answer.ToQuestionId) <br />
@Html.Hidden("Answers[" + i + "].ToQuestionId", answer.ToQuestionId)
@Html.Label("Answers[" + i + "].QuestionText", answer.QuestionText)
@*
to save bandwidth we didn't include QuestionText on submit,
this is done by assigning it on Label, and no need to persist
QuestionText on Hidden
*@
<br />
@Html.TextArea("Answers[" + i + "].AnswerText", answer.AnswerText)
<hr />
++i;
}
<input type="submit" value="Done" />
}
查看主页/提交答案
@model SoQna.ViewModels.QnaViewModel
@{
ViewBag.Title = "SubmitAnswers";
}
<h2>SubmitAnswers</h2>
@foreach (var item in Model.Answers)
{
@: Answer to question: @item.QuestionText
<br />
@item.AnswerText
<hr />
}