我有两个模型,问题和答案。我想通过 ViewModel 插入问题的答案列表,但在我的 post 方法中,我的列表似乎为空。这也可能是一个糟糕的实现,因为当我发布某些内容时,我会返回问题的模型,并且我猜我的列表即将变为空。我该如何解决这个问题?
编辑:我根据您给我的评论重新制作了 Controller 和 View :这就是它现在的样子,但似乎我的答案列表再次为空。
View 模型:
public class ViewModel
{
public IEnumerable<Answer> Answers { get; set; }
public Question Question { get; set; }
}
Controller :
[Authorize]
public ActionResult Create()
{
ViewModel vm = new ViewModel();
ViewBag.BelongToTest = new SelectList(db.Tests, "TestId" , "TestTitle").FirstOrDefault();
vm.Question = new Question { Question_Text = String.Empty };
vm.Answers = new List<Answer> { new Answer { CorrectOrNot = false, AnswerText = "", OpenAnswerText = "" } };
return View(vm);
}
//
// POST: /Question/Create
[HttpPost]
[Authorize]
public ActionResult Create(ViewModel vm)
{
if (ModelState.IsValid)
{
vm.Question.BelongToTest = (from t in db.Tests
join m in db.Members on t.AddedByUser equals m.MemberId
where m.UserID == WebSecurity.CurrentUserId &&
t.AddedByUser == m.MemberId
orderby t.TestId descending
select t.TestId).FirstOrDefault();
db.Questions.Add(vm.Question);
db.SaveChanges();
if (vm.Answers != null)
{
foreach (var i in vm.Answers)
{
i.BelongToQuestion = vm.Question.QuestionId;
db.Answers.Add(i);
}
}
db.SaveChanges();
ViewBag.Message = "Data successfully saved!";
ModelState.Clear();
}
ViewBag.BelongToTest = new SelectList(db.Tests, "TestId", "TestTitle", vm.Question.BelongToTest);
vm.Question = new Question { Question_Text = String.Empty };
vm.Answers = new List<Answer> { new Answer { CorrectOrNot = false, AnswerText = "", OpenAnswerText = "" } };
return View("Create" , vm);
}
查看:
@model MvcTestApplication.Models.ViewModel
@using MvcTestApplication.Models
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
@{
ViewBag.Title = "Create";
}
@using (Html.BeginForm("Create", "Question", FormMethod.Post)) {
<h2>Create</h2>
<table>
<tr>
<th>Question Name</th>
</tr>
<tr>
<td>@Html.EditorFor(model=>model.Question.Question_Text)</td>
</tr>
</table>
<table id="dataTable">
<tr>
<th>Correct?</th>
<th>Answer text</th>
<th>Open Answer</th>
</tr>
@foreach(var i in Model.Answers)
{
<tr>
<td>@Html.CheckBoxFor(model=>i.CorrectOrNot)</td>
<td>@Html.EditorFor(model=>i.AnswerText)</td>
<td>@Html.EditorFor(model=>i.OpenAnswerText)</td>
</tr>
}
</table>
<input type="button" id="addNew" value="Add Answer"/>
<input type="submit" value="Create" />
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script lang="javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\d+/);
$trNew.find("td:last").html('<a href="#" class="remove">Remove</a>');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
if (type.toLowerCase() == "text") {
$(this).attr('value', '');
}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
// Re-assign Validation
var form = $("form")
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
// 2. Remove
$('a.remove').live("click", function (e) {
e.preventDefault();
$(this).parent().parent().remove();
});
});
</script>
}
最佳答案
为了将 ModelBinder 绑定(bind)到 List,HTML 表单必须按顺序索引。
你的
<td>@Html.CheckBoxFor(model=>a.CorrectOrNot)</td>
<td>@Html.EditorFor(model=>a.AnswerText)</td>
<td>@Html.EditorFor(model=>a.OpenAnswerText)</td>
正在创建一些与个人答案绑定(bind)的东西。您需要渲染将绑定(bind)到列表的 HTML,例如
@for (int i = 0; i < ((List<Answer>)ViewData["Answers"]).Count; i++)
{
<tr>
<td>@Html.CheckBoxFor(model=>((List<Answer>)ViewData["Answers"])[i].CorrectOrNot)</td>
<td>@Html.EditorFor(model=>((List<Answer>)ViewData["Answers"])[i].AnswerText)</td>
<td>@Html.EditorFor(model=>((List<Answer>)ViewData["Answers"])[i].OpenAnswerText)</td>
</tr>
}
此外,将 ViewData 转换到各处看起来非常糟糕。如果您打算保留这种方法来创建真实的 View 模型,通常会更好。您可以将该模型传递给 View ,它可以包装问题和答案集合。
编辑:
您仍然需要针对您的列表有一个顺序索引,而您编辑的实现未提供该索引。类似的东西
@for (int i = 0; i < Model.Answers.Count; i++)
{
<tr>
<td>@Html.CheckBoxFor(model=> Model.Answers[i].CorrectOrNot)</td>
<td>@Html.EditorFor(model=> Model.Answers[i].AnswerText)</td>
<td>@Html.EditorFor(model=> Model.Answers[i].OpenAnswerText)</td>
</tr>
}
关于asp.net-mvc - 为什么我的 ViewData 列表为空?微 Controller 4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29368424/