asp.net-mvc - 为什么我的 ViewData 列表为空?微 Controller 4

标签 asp.net-mvc asp.net-mvc-4 viewdata

我有两个模型,问题和答案。我想通过 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/

相关文章:

asp.net - User.Identity.Name 和 User.Identity.IsAuthenticated 是什么集合?

asp.net-mvc - debug 加载当前 View 而不是在routeconfig Mvc 4 中指定的 View

c# - 当负载均衡器不是 "sticky"时,如何在 MVC 的 Session 中保存数据?

asp.net-mvc - 如何让窗体中的 ViewData 正确显示?

javascript - jquery jcarousel 错误 : Uncaught TypeError: Object #<Object> has no method 'jcarousel'

model-view-controller - mvc 没有代码隐藏强类型 View 数据头不起作用

c# - 扩展 Telerik 客户端模板列并获取通过的值

ASP.NET 成员(member) : CSS being blocked by Deny users, 页面无法正确呈现?

c# - 在 ASP.NET MVC 4 C# Code First 中指定 ON DELETE NO ACTION

asp.net-mvc-4 - 禁止从地址栏中调用操作方法