我有两个模型,问题和答案。 我想通过ViewModel插入问题的答案列表,但是在我的post方法中,我的列表似乎为空。 这也可能是一个不好的实现,因为在发布某些内容时,我将返回问题的模型,并且我猜我的List只是为空。 我该如何解决?

编辑:我根据您给我的评论重新制作了控制器和视图:那就是现在的样子,但看来我的答案列表再次为空。

视图模型:

 public class ViewModel
{
    public IEnumerable<Answer> Answers { get; set; }
    public Question Question { get; set; }
}

控制器:

[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>
          }

#1楼 票数:3 已采纳

为了使ModelBinder绑定到列表,必须按顺序索引HTML表单。

你的

<td>@Html.CheckBoxFor(model=>a.CorrectOrNot)</td>
<td>@Html.EditorFor(model=>a.AnswerText)</td>
<td>@Html.EditorFor(model=>a.OpenAnswerText)</td>

正在创建将绑定到单个答案的内容。 您需要呈现将绑定到列表的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看起来非常糟糕。 如果您打算保留这种方法来创建真实视图模型,通常会更好。 您可以将该模型传递给视图,并且可以包装问题和答案集合。

编辑:

您仍然需要针对您的列表提供一个顺序索引,该列表是您已编辑的实现未提供的。 就像是

@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>
}

#2楼 票数:1

从控制器转到视图时,ViewData是相关的。 它不会回发。

您应该中继(模型/参数)绑定,该绑定将为您传递List<Answer> answerList

#3楼 票数:0

ViewData仅用于在视图和控制器之间传输数据。 您可以使用会话在控制器之间传输数据

#4楼 票数:0

感谢您的评论。 他们真的帮助了我。 您说的都是正确的,但有一些遗漏的地方。 我在ViewModel中的IEnumerable根本不允许我对值进行索引,而是使用IList帮助我对应该按原样进行的一切进行索引并且一切正常。

  ask by vLr translate from so

未解决问题?本站智能推荐:

1回复

在MVC,Razor中的ViewData项目列表中显示索引的文本值

我会尽量保持简短。 我是MVC的新手。 我有一个Controller,它创建一个时隙列表(如时间表),并将其放入ViewData中。 我知道该怎么做。 我知道如何使用@Html.DropDownList在下拉菜单中显示此数据,例如,我的创建页面具有以下内容: 我的问题是在索引视图
2回复

如何在MVC4的局部视图中访问动态linq查询的结果(PredicateBuilderlinq到实体)?

我有一个控制器操作,该操作使用PredicateBuilder构建动态linq查询。 我想将此查询的结果传递给局部视图。 做这个的最好方式是什么? 如果最佳做法是始终使用强类型视图,那么传递给控制器​​操作的视图模型是否应该具有可将查询结果传递到其中的列表? 还是使用两个列表只是额外的开
1回复

在mvc2中从ViewData获取列表数据

我正在尝试从查看数据中获取数据列表这是从数据库中获取所有客户端列表的方法 这是控制器 这是视图 这回来了我 问题是我如何才能一一列出清单中的所有数据
4回复

MVC用户控件+ViewData

嗨,我是MVC新手,我已经四处乱窜,如何构建将ViewData返回给他们的MVC用户控件。 我希望有人会就如何解决这个问题提出一步一步的解决方案。 如果你能使你的解决方案非常详细,那将会有很大帮助。 很抱歉因为我的问题如此离散,我想澄清我最终尝试做的是将id传递给控制器​​actionr
1回复

在mvc剃刀的Viewdata

我正在使用MVC 3.0(Razor框架)进行项目。 我试图从控制器获取值,使用View按钮点击Javascript方法。它来自document.ready而不是按钮点击。所以请帮助获取按钮点击上的viewdata值。 以下是我的代码 我的JAvascript代码: 我想在按钮点击
1回复

MVC-有型“的IEnumerable”没有ViewData的项目具有关键“*******”

这让我很烦。 如果完成并提交表格,它可以很好地处理负载。 但是,如果我不更新任何值,则由于空值而应生成验证错误,它将显示以下错误。 $ exception {“没有类型为“ IEnumerable”的ViewData项,其键为“ TenantType”。”} System.Except
1回复

MVC如何隐藏通过ViewData传递的值

想知道是否有人可以提供帮助,我正在从控制器传递值以查看: 结果的值显示在返回的视图的URL中,是否可以隐藏该值? 我知道从视图到控制器,您将其设置为隐藏的输入类型,但是如何从控制器到视图执行相同的操作? 任何帮助表示赞赏
4回复

ASP.NETMVC2-POST后的ViewData为空

我真的不知道在哪里寻找错误......情况:我有一个ASPX视图,其中包含一个表单和一些输入,当我点击提交按钮时,一切都被POST到我的一个ASP。 NET MVC操作。 当我在那里设置断点时,它被正确击中。 当我使用FireBug查看发送到操作的内容时,我正确地看到data1 = abc