【问题标题】:ASP.NET MVC 4.0 model binder not working with collectionASP.NET MVC 4.0 模型绑定器不适用于集合
【发布时间】:2014-01-16 08:13:33
【问题描述】:

默认模型绑定器不会映射我模型中的集合。这是我的代码:

型号:

public class Company
{
   public string Name;
   public List<CompanyActivity> Activities
}

public class CompanyActivity
{
   public string  Code;
   public string Description
}

控制器:

[HttpPost]
public ActionResult Index(Company company) {}

查看/HTML:

<input name="Name" type="text" value="some name" />
<input name="Activities[0].Code" type="text" value="1" />
<input name="Activities[0].Description" type="text" value="a" />
<input name="Activities[1].Code" type="text" value="2" />
<input name="Activities[1].Description" type="text" value="b" />

名称输入已映射,但活动列表为空。

【问题讨论】:

  • 您提供的 HTML 将 value="" 属性显示为空。当你提供值时会发生什么?另外,您的 MVC 视图源是什么?

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


【解决方案1】:

您已经使用字段定义了模型,但您必须使用属性。您只需为此更改模型:

public class Company
{
    public string Name { get; set; }
    public List<CompanyActivity> Activities { get; set; }
}

public class CompanyActivity
{
    public string Code { get; set; }
    public string Description { get; set; }
}

字段和属性的区别:Difference between Property and Field in C# 3.0+ASP.net MVC - Model binding excludes class fields?

【讨论】:

  • 为什么?我用你的代码创建了一个项目。没有属性不绑定和属性绑定正确。 HTML 是正确的,就像我说我只添加了 {get;set;} 并且它工作正常。
  • 有趣的是,我没有意识到模型绑定器足够聪明,可以使用该名称语法来执行此操作。相比之下,我的回答几乎没有那么整洁。
【解决方案2】:

名称必须相同才能将它们构建为集合/数组:

我会创建一个 ViewModel 来处理这种情况,这就是为什么我几乎总是构建一个 ViewModel 来处理视图渲染和 MVC 的特性。

型号

public class Company
{
   public string Name;
   public List<CompanyActivity> Activities
}

视图模型

public class CompanyViewModel
{
   public string Name;

   //View specific
   public List<int> CompanyActivityCodes
}

查看

<input name="Name" type="text" value="" />
<input name="CompanyActivityCodes" type="text" value="" />
<input name="CompanyActivityCodes" type="text" value="" />

这将绑定 CompanyActivityCodes 属性,然后您可以重新分配这些以在控制器中构建活动属性。

public ActionResult Index(CompanyViewModel companyViewModel) 
{
  var company = new Company { Name = companyViewModel }; 
  company.Activities = companyViewModel.CompanyActivityCodes.Select(x =>  new CompanyActivity { Code = x });
}

【讨论】:

  • 我已经更新了我的代码。活动是对象列表,而不是整数列表。
  • 是的,但是在使用集合时它可以找出嵌套属性并不是那么聪明。
  • 我明白,modelbinder 不够先进,但是在处理集合时无法确定嵌套属性。出于这个原因,我创建了一个 ViewModel,它基本上将您的 CompanyActivity 类“扁平化”为扁平类。如您所见,我已将属性命名为 CompanyActivityCodes,因为它会展平活动集合中的 code 属性。您已编辑问题以包含使问题复杂化的其他属性。
【解决方案3】:

应该是

<input name="company.Activities[0].Code" type="text" value="" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多