asp.net mvc 模型绑定不绑定集合

问题描述 投票:0回答:2

我无法理解 asp.net mvc 模型绑定器的工作原理。

型号

public class Detail
{
  public Guid Id { get; set; }
  public string Title {get; set; }    
}

public class Master
{
  public Guid Id { get; set;}
  public string Title { get; set; }
  public List<Detail> Details { get; set; }
}

查看

 <!-- part of master view in ~/Views/Master/EditMaster.cshtml -->
 @model Master

 @using (Html.BeginForm())
 {
     @Html.HiddenFor(m => m.Id)
     @Html.TextBoxFor(m => m.Title)

     @Html.EditorFor(m => m.Details)

     <!-- snip -->
 }

 <!-- detail view in ~/Views/Master/EditorTemplates/Detail.cshtml -->
 @model Detail

 @Html.HiddenFor(m => m.Id)
 @Html.EditorFor(m => m.Title)

控制器

// Alternative 1 - the one that does not work
public ActionResult Save(Master master)
{
   // master.Details not populated!
}

// Alternative 2 - one that do work
public ActionResult Save(Master master, [Bind(Prefix="Details")]IEnumerable<Detail> details)
{
   // master.Details still not populated, but details parameter is.
}

渲染的html

<form action="..." method="post">
  <input type="hidden" name="Id" value="....">
  <input type="text" name="Title" value="master title">
  <input type="hidden" name="Details[0].Id" value="....">
  <input type="text" name="Details[0].Title value="detail title">
  <input type="hidden" name="Details[1].Id" value="....">
  <input type="text" name="Details[1].Title value="detail title">
  <input type="hidden" name="Details[2].Id" value="....">
  <input type="text" name="Details[2].Title value="detail title">
  <input type="submit">
</form>

为什么要使用默认模型绑定器填充模型上的详细信息属性?为什么我必须将其作为单独的参数包含到控制器中?

我读过多篇关于 asp 和绑定到列表的文章,包括在其他问题中多次提到的 Haackeds。正是 SO 上的this thread引导我选择了

[Binding(Prefix...)]
选项。它说“模型可能太复杂”,但是对于默认模型绑定器来说“太复杂”到底是什么?

c# asp.net asp.net-mvc asp.net-mvc-4 razor
2个回答
0
投票

您问题中的模型并不算“太复杂”。 然而,复杂类型的列表(例如您的 Details 对象)将是一个复杂的绑定。

对于复杂的绑定,使用编辑器模板。此 editorTemplate 指定如何呈现复杂类型的编辑器。正在视图所在文件夹内的“EditorTemplates”文件夹中搜索 EditorTemplates。默认情况下,编辑器模板必须具有复杂类型类的名称。因此,在您的情况下,您应该将其命名为 Detail.cshtml

在编辑器模板中,您可以使用类似以下内容:

@model Detail

@Html.HiddenFor(m => m.Id)
@Html.TextBoxFor(m => m.Title)

现在,当您在常规模型中调用

@Html.EditorFor(m => m.Details)
时,对于详细信息列表中的每个项目,将呈现指定的编辑器模板。

在操作指向的控制器中,您可以只请求模型的一个实例,例如:

public ActionResult Save(Master model)
{ 

}

现在在 Save 方法中,

model.Details
将填充您视图中的数据。

请注意,MVC 只会将表单中可用的数据返回到控制器。所有未呈现或不在表单内的数据都不会被返回。


0
投票

如果使用 AJAX 发送数据,请确保请求 Content-Type 标头设置为 application/x-www-form-urlencoded,而不是其他类型,例如 application/json。

© www.soinside.com 2019 - 2024. All rights reserved.