我有一个简单的课程:
[Serializable]
public class RatePerPurpose
{
public int ValueId { get; set; }
public double Rate { get; set; }
}
,以及POST的简单数据:
<input type="hidden" name="[0].ValueId" value="1" />
<input type="hidden" name="[0].Rate" value="2.34" />
<input type="hidden" name="[1].ValueId" value="10" />
<input type="hidden" name="[1].Rate" value="20.34" />
这没有任何问题:
[HttpPost]
public virtual ActionResult MyActionPost(List<RatePerPurpose> rates)
{
// no problem, this works
}
我的问题是,为什么这些不起作用(我测试过ASP.NET MVC 5)?或者如何改变它,使其有效?
[HttpPost]
public virtual ActionResult MyActionPost()
{
List<RatePerPurpose> rates = new List<RatePerPurpose>();
this.UpdateModel(rates);
// This DOES NOT work, 'rates' is empty :-(
this.UpdateModel(rates, prefix:"");
// Setting 'none' prefix, also DOES NOT work. 'rates' is still empty
}
PS:我也测试了List<>
和IList<>
,但也出现了同样的问题。
答案 0 :(得分:0)
问题是在第二个示例中,您有一个空列表。 UpdateModel
会更新项(如果它们存在且可以找到相关性),但它不会为您填充空列表。如果你做了类似的事情:
var rates = db.RatePerPurposes.ToList();
UpdateModel(rates);
那个可能会起作用,假设它可以将POST主体中的RatePerPurpose
个实例与数据库返回的RatePerPurpose
个实例进行匹配。
答案 1 :(得分:0)
我终于想通了(在三个不眠之日之后)。实际上有两个问题。
问题1
我的应用程序的global.asax在DoubleModelBinder
上调用了Application_Start
深刻的({注册}}:
...
ModelBinders.Binders.Add(typeof(double), new DoubleModelBinder());
...
此绑定程序依赖于UICulture
,因此从action方法参数绑定起作用。但是MyActionPost()
的身体有不同的文化,所以我的DoubleModelBinder
抛出了一些内部异常。有点奇怪,这个异常没有传播出UpdateModel()
。
问题2
在我的示例中使用UpdateModel()
(或TryUpdateModel()
)非常好。我在第654页的Adam Freeman的书Pro ASP.NET MVC 5中也找到了类似的示例,但“正确”版本应使用FormCollection
作为操作方法参数。如此工作的例子:
[HttpPost]
public virtual ActionResult MyActionPost(FormCollection form)
{
List<RatePerPurpose> rates = new List<RatePerPurpose>();
this.UpdateModel(rates, "MyList", form);
// This works, 'rates' is binded properly
}
<强> PS:强>
最后一条建议。绑定集合时使用.Index
。 (当索引来自0并且项目之间没有间隙时,这不是必需的,但我现在可以睡得更好。:)所以数据应该如下所示:
<input type="hidden" name="MyList.Index" value="0" />
<input type="hidden" name="MyList[0].ValueId" value="1" />
<input type="hidden" name="MyList[0].Rate" value="2.34" />
<input type="hidden" name="MyList.Index" value="1" />
<input type="hidden" name="MyList[1].ValueId" value="10" />
<input type="hidden" name="MyList[1].Rate" value="20.34" />