C# 为什么IList的UpdateModel()绑定不起作用,但作为方法参数起作用?
我有一个简单的课程:C# 为什么IList的UpdateModel()绑定不起作用,但作为方法参数起作用?,c#,asp.net,.net,asp.net-mvc,asp.net-mvc-5,C#,Asp.net,.net,Asp.net Mvc,Asp.net Mvc 5,我有一个简单的课程: [Serializable] public class RatePerPurpose { public int ValueId { get; set; } public double Rate { get; set; } } ,以及要发布的简单数据: <input type="hidden" name="[0].ValueId" value="1" /> <input type="hidden" name="[0].Rate" valu
[Serializable]
public class RatePerPurpose
{
public int ValueId { get; set; }
public double Rate { get; set; }
}
,以及要发布的简单数据:
<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
}
[HttpPost]
公共虚拟行动结果MyActionPost(列出费率)
{
//没问题,这管用
}
我的问题是,为什么这些不起作用(我已经测试过ASP.NETMVC5)?或者如何改变这一点,使其发挥作用
[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
}
[HttpPost]
公共虚拟操作结果MyActionPost()
{
列表费率=新列表();
此.UpdateModel(费率);
//这不起作用,“费率”为空:-(
this.UpdateModel(费率,前缀:“”);
//设置“none”前缀也无效。“rates”仍然为空
}
PS:我也测试了
List
和IList
,但同样的问题也出现了。问题是,在第二个示例中,您有一个空列表。UpdateModel
将更新项目,如果它们存在,它可以找到相关性,但它不会为您填充一个空列表。如果您改为执行以下操作:
var rates = db.RatePerPurposes.ToList();
UpdateModel(rates);
假设它可以将POST body中的
RatePerPurpose
实例与从数据库返回的RatePerPurpose
实例相匹配,那么这可能会起作用。我终于找到了答案(经过三天不眠之夜)。实际上有两个问题
问题1
在我的应用程序的global.asax上调用了application\u Start
,发现有bugDoubleModelBinder
:
...
ModelBinders.Binders.Add(typeof(double), new DoubleModelBinder());
...
此绑定器依赖于UICulture
,因此从操作方法参数进行绑定是可行的。但是MyActionPost()
的主体具有不同的区域性,因此我的DoubleModelBinder
引发了一些内部异常。有点奇怪,此异常没有从UpdateModel()
传播出去
问题2
在我的示例中使用UpdateModel()
(或TryUpdateModel()
)是非常好的。我在亚当·弗里曼(Adam Freeman)第654页的一本书中也发现了类似的示例,但“正确”版本应该使用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
}
不起作用是什么意思?
是否出现异常?是否什么都没有发生?首先为什么要使用UpdateModel
?rates
在UpdateModel()
之后为空(为了清楚起见,我将编辑我的问题)我的实际操作方法要大得多,有更多的参数和逻辑。我刚刚将一个问题隔离为一个简单的问题。所以简单的答案是我需要UpdateModel()
.Period.:-)你真的有列表作为模型吗?您是否尝试过将列表包装到适当的模型/视图模型中?什么是适当的模型/视图模型
<代码>列表
不是一个合适的模型?我的意思是将列表包装在某个类中,您将使用该类作为视图和控制器的模型。我认为MVC的一个要点是视图和控制器共享一个模型(可能是一个容器,用于一堆其他类等)UpdateModel
的设计也考虑到了这一点——它不是用来传递参数的,而是用来允许您更改已经存在的对象中的值(例如,您在数据库中有一个Person
对象,您想要获取它,更改请求中发送的值并将其保存回去)。
<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" />