【问题标题】:MVC Razor View: How to render a list of text boxes for a List<Task> in the model?MVC Razor View:如何为模型中的 List<Task> 呈现文本框列表?
【发布时间】:2019-03-23 13:59:44
【问题描述】:

我的模型中有一个List&lt;Task&gt;。此列表包含 2 个任务(比如说)

public List<Task> Tasks { get; set; }

public class Task    {
    public Task()
    {
        Title="";
        Total= 0;
    }

    public string Title{ get; set; }

    public int Total{ get; set; }
}

现在在我的 razor 视图中,我想为模型的 List&lt;Tasks&gt; 中的每个 Tasks 渲染 2 个文本框。

我没有循环,只是放置了直接文本框,例如:

@Html.TextBoxFor(m => m.Tasks[0].Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Tasks[0].Total, new { @maxlength = "2"})
<br>
@Html.TextBoxFor(m => m.Tasks[1].Title, new { @maxlength = "50"})
@Html.TextBoxFor(m => m.Tasks[1].Total, new { @maxlength = "2"})

这可以很好地呈现表单,但在 FF 中单击提交按钮不会执行任何操作。 但是它在 IE9 中可以正常发布。

查看源代码显示此 html 生成如下:

<input id="Tasks_0__Title" maxlength="50" name="Tasks[0].Title" type="text" value="" />
<input data-val="true" data-val-number="The field Total must be a number." data-val-required="The Total field is required." id="Tasks_0__Total" maxlength="2" name="Tasks[0].Total" type="text" value="" /> 

此 HTML 看起来不正确。它有name="Tasks[0].Total",这看起来很奇怪。

我应该怎么做才能在发布后从控制器中的List&lt;&gt; 访问文本框值?

谢谢

编辑: 我只保留一排进行测试。这是我在FF看到的html。

<input id="Tasks_0__Title" type="text" value="" name="Tasks[0].Title" maxlength="50">
<input id="Tasks_0__Total" type="text" value="" name="Tasks[0].Total" maxlength="2" data-val-required="The Total field is required." data-val-number="The field Total must be a number." data-val="true">

当我点击提交按钮时,这不会发布。

现在如果我改变name="Tasks[0].Title" to name="Tasks_0__Title" and name="Tasks_0__Total" 在 FIREBUG 中它可以正常发布。

如果我完全删除名称,它也会在 FF 中正常发布

【问题讨论】:

    标签: asp.net-mvc-3 razor


    【解决方案1】:

    您应该使用Tasks[0].TotalTasks[1].Total 而不是Items

    @Html.TextBoxFor(m => m.Tasks[0].Title, new { @maxlength = "50"})
    @Html.TextBoxFor(m => m.Tasks[0].Total, new { @maxlength = "2"})
    <br/>
    @Html.TextBoxFor(m => m.Tasks[1].Title, new { @maxlength = "50"})
    @Html.TextBoxFor(m => m.Tasks[1].Total, new { @maxlength = "2"})
    

    name="Tasks[0].Total" 并不奇怪。这正是输入的命名方式,以便模型绑定器在 POST 操作中取回值。请参阅this blog post,了解默认模型绑定器在处理列表和字典时使用的连线格式。

    话虽如此,我建议您使用编辑器模板 => 而不是在您的视图中编写这 5 行代码,将它们替换为:

    @Html.EditorFor(x => x.Tasks)
    

    然后在相应的编辑器模板 (~/View/Shared/EditorTemplates/Task.cshtml) 中,将为Tasks 集合中的每个元素自动呈现:

    @model Task
    @Html.TextBoxFor(m => m.Title, new { @maxlength = "50"})
    @Html.TextBoxFor(m => m.Total, new { @maxlength = "2"})    
    <br/>
    

    现在您可以让编辑器模板担心正确的命名约定等...

    就您的 POST 操作而言:

    [HttpPost]
    public ActionResult Foo(MyViewModel model)
    {
        // model.Tasks should be correctly bound here
        ...
    }
    

    【讨论】:

    • 达林,你确定 name="Tasks[0].Total" 不奇怪吗?我刚刚在FF中测试过。如果我单击提交按钮,这些 FF 不会发布到服务器。如果我将 Firebug 中的所有名称从 Tasks[0].Total 更改为 Tasks_0__Total,那么它可以正常发布。生成的 id 看起来像 Tasks_0__Total、Tasks_1__Total 但它们很好,但名称中有 [0]。有什么方法可以排除名称生成?
    • @Projapati,ID 无关紧要。这是用于发送到服务器的name 属性。正确的名称是 Tasks[0].Total,正如我链接到的 Scott Hanselman 的 blog post 中所解释的那样。
    • Name = ListName[index].PropertyName 在 FF 4.0.1 中炸毁 Html.BeginForm() 如果我单击提交按钮,则不会发布。如果我将名称更改为使用下划线而不是 [0] 它会发布。有什么原因吗?
    • @Projapati,没有理由,对我来说很好。什么轰炸?你收到错误消息还是什么?
    • 我的意思是点击提交按钮没有任何作用。该按钮在 FF、Chrome、Opera 中已失效。但适用于 IE9。
    【解决方案2】:

    如果您想拥有多个带有文本框的元素。

     for (int i = 0; i < Model.Students.Count; i++)
                                {
                                    @Html.HiddenFor(modelIem => Model.Students[i].StudentId)
    
                                    <tr>
                                        <td>
                                            @Html.DisplayFor(modelItem => Model.Students[i].Student.FirstNames)
                                        </td>
                                        <td>
                                            @Html.DisplayFor(modelItem => Model.Students[i].Student.LastNames)
                                        </td>
                                        <td>
                                            @Html.TextBoxFor(modelItem => Model.Students[i].Score, new { @type = "number" })
                                        </td>
    </tr> }
    

    这是视图模型

    public class MyModel 
    {
     public List<StudentGrade> Students { get; set; }
        }
    
        public class StudentGrade {
            public ApplicationUser Student { get; set; }
            [Range(1, 100)]
            public int? Score { get; set; } = null;
            public string Description { get; set; } = null;
            public string StudentId { get; set; }
        }
    

    最后它看起来像这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 2023-01-10
      • 1970-01-01
      • 2017-11-08
      相关资源
      最近更新 更多