【问题标题】:MVC4 bind model to ICollection or List in partialMVC4 将模型部分绑定到 ICollection 或 List
【发布时间】:2013-02-07 12:18:22
【问题描述】:

给定一个模型

public class Task
{
public int TaskId { get; set; }
public string Title { get; set; }
public ICollection<SomeData> Information { get; set; }
}

在哪里

public class SomeData
{
    public int SomeDataId { get; set; }
    public string Description { get; set; }
}

我有意见

@model myProject.Models.Task

<div>
    @Html.LabelFor(model => model.Title)
</div>

<table>
@Html.Partial("_InformationEdit", Model.Information.ToList(), new ViewDataDictionary(Html.ViewDataContainer.ViewData) {
                TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Information" }})
</table>                    

我的部分是

@model IList<myProject.Models.SomeData>

@for (int i = 0; i < Model.Count(); i++)
{
    <tr>
        <td>
            @Html.EditorFor(modelItem => Model[i].Description)
        </td>
    </tr>
 }

但是

我的 Html 字段被渲染为

<input class="text-box single-line" id="Information__0__Description" name="Information.[0].Description" type="text">

名称应该是Information[0].Description。它在那里有一个额外的点,因此在发布时没有正确绑定回模型。我该如何解决这个问题?

根据 Model binding to a list,我可以看到我的 ID 应该是什么,但我就是想不出正确的语法。

另外,有没有更优雅的方法可以通过IEnumerable 使用@foreach 来实现这一点?

相关:

ASP.Net MVC4 bind a "create view" to a model that contains List

ASP.NET MVC model binding an IList<> parameter

【问题讨论】:

    标签: c# asp.net razor asp.net-mvc-4 model-binding


    【解决方案1】:

    您可以像这样直接使用&lt;input...

    页面:

    <table>
        @Html.Partial("_InformationEdit", Model.Information)
    </table>
    

    部分页面:

    @for (int i = 0; i < Model.Count(); i++)
    {
        <tr>
            <td>
                <input class="text-box single-line" id="Information[@i]Description" name="Information[@i].Description" type="text" value="@Model[i].Description" />
            </td>
        </tr>
    }
    

    或者,为了能够像您的示例一样传递前缀,您可以保持页面代码相同并更改您的部分代码:

    页面:

    <table>        
        @Html.Partial("_InformationEdit", Model.Information, 
            new ViewDataDictionary(Html.ViewDataContainer.ViewData) 
            {
                TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Information" }
            })
    </table>
    

    部分页面:

    @for (int i = 0; i < Model.Count(); i++)
    {
        <tr>
            <td>
                @{
                    string fieldName = string.Format("{0}[{1}].Description", ViewData.TemplateInfo.HtmlFieldPrefix, i);
                    <input class="text-box single-line" id="@fieldName" name="@fieldName" type="text" value="@Model[i].Description" />
                }
            </td>
        </tr>
    }
    

    【讨论】:

    • 谢谢你,但是如果扩展的情况下可能对模型进行验证(它将由 EditorFor 自动创建)呢?
    【解决方案2】:

    将我的部分更改为

    @model IList<myProject.Models.SomeData>
    
    @{
        var Information = Model;
    }
    
    @for (int i = 0; i < Information.Count(); i++)
    {
        <tr>
            <td>
                @Html.EditorFor(modelItem => Information[i].Description)
            </td>
        </tr>
     }
    

    有效,但这似乎有点奇怪!

    我想确保被绑定的对象与它需要绑定的属性同名会做一些魔法......欢迎其他建议或解释!

    【讨论】:

      【解决方案3】:

      你的部分应该是:

      @model IList<myProject.Models.SomeData>
      
      @for (int i = 0; i < Model.Count(); i++)
      {
        <tr>
          <td>
            @Html.EditorFor(model => model[i].Description)
          </td>
        </tr>
      }
      

      如果您将 i 替换为项目名称,则更易于阅读

      【讨论】:

      • 它与问题不同(虽然我不知道它是否是一个解决方案)因为在问题中直接访问模型,但是这里它只能通过 lambda 参数访问
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多