C# ASP.Net MVC - 带有集合的模型不会在回发时填充
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/887505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.Net MVC - model with collection not populating on postback
提问by Richbits
I have an ASP.Net MVC application with a model which is several layers deep containing a collection.
我有一个 ASP.Net MVC 应用程序,其中包含一个包含集合的多层模型。
I believe that the view to create the objects is all set up correctly, but it just does not populate the collection within the model when I post the form to the server.
我相信创建对象的视图都设置正确,但是当我将表单发布到服务器时,它不会填充模型中的集合。
I have a piece of data which is found in the class hierarchy thus:
我有一个在类层次结构中找到的数据,因此:
person.PersonDetails.ContactInformation[0].Data;
This class structure is created by LinqToSQL, and ContactInformation is of type EntitySet<ContactData>
. To create the view I pass the following:
这个类结构是由 LinqToSQL 创建的,ContactInformation 的类型是EntitySet<ContactData>
。要创建视图,我传递了以下内容:
return View(person);
and within the view I have a form which contains a single text box with a name associated to the above mentioned field:
在视图中,我有一个表单,其中包含一个文本框,其名称与上述字段相关联:
<%= Html.TextBox("person.PersonDetails.ContactInformation[0].Data")%>
The post method within my controller is then as follows:
我的控制器中的 post 方法如下:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create (Person person)
{
//Do stuff to validate and add to the database
}
It is at this point where I get lost as person.PersonDetails.ContactInformation.Count() ==0. So the ModelBinder has created a ContactInformation object but not populated it with the object which it should hold (i.e ContactData) at index 0.
正是在这一点上,我迷失了 person.PersonDetails.ContactInformation.Count() ==0。所以 ModelBinder 已经创建了一个 ContactInformation 对象,但没有用它应该在索引 0 处保存的对象(即 ContactData)填充它。
My question is two fold: 1. Have I taken the correct approach.. i.e. should this work? 2. Any ideas as to why it might be failing to populate the ContactInformation object?
我的问题有两个方面: 1. 我是否采取了正确的方法.. 即这应该有效吗?2. 关于为什么可能无法填充 ContactInformation 对象的任何想法?
Many thanks, Richard
非常感谢,理查德
采纳答案by tvanfosson
I think that your model is too complex for the default model binder to work with. You could try using multiple parameters and binding them with prefixes:
我认为您的模型对于默认模型绑定器来说太复杂了。您可以尝试使用多个参数并使用前缀绑定它们:
public ActionResult Create(
Person person,
[Bind(Prefix="Person.PersonDetails")]
PersonDetails details,
[Bind(Prefix="Person.PersonDetails.ContactInformation")]
ContactInformation[] info )
{
person.PersonDetails = details;
person.PersonDetails.ContactInformation = info;
...
}
Or you could develop your own custom model binder that would understand how to derive your complex model from the form inputs.
或者您可以开发自己的自定义模型绑定器,以了解如何从表单输入中导出复杂模型。
回答by Arnis Lapsa
Maybe lack of Bind attribute is the case:
也许缺少 Bind 属性是这种情况:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create ([Bind] Person person)
{
// Do stuff to validate and add to the database
}
回答by Ropstah
The first argument of Html.TextBox is the name of the textbox, the second would be the value.
Html.TextBox 的第一个参数是文本框的名称,第二个参数是值。
"Wrong":
“错误的”:
<%= Html.TextBox("person.PersonDetails.ContactInformation[0].Data")%>
"Right":
“对”:
<%= Html.TextBox("nameoftextbox", person.PersonDetails.ContactInformation[0].Data)%>
回答by Craig Stuntz
If a property is null, then the model binder other could not find it or could not find values in the submitted form necessary to make an instance of the type of the property. For example, if the property has a non-nullable ID and your form does not contain any data for that ID , the model binder will leave the property as null since it cannot make a new instance of the type without knowing the ID.
如果属性为空,则模型绑定器无法找到它或无法在提交的表单中找到创建属性类型实例所需的值。例如,如果属性具有不可为空的 ID,并且您的表单不包含该 ID 的任何数据,则模型绑定器会将属性保留为 null,因为它无法在不知道 ID 的情况下创建该类型的新实例。
In other words, to diagnose this problem you must carefully compare the data in the submitted form (this is easy to see with Firebug or Fiddler) with the structure of the object you are expecting the model binder to populate. If any required fields are missing, or if the values are submitted in such a way that they cannot be converted to the type of a required field, then the entire object will be left null.
换句话说,要诊断此问题,您必须仔细比较提交表单中的数据(这在 Firebug 或 Fiddler 中很容易看到)与您希望模型绑定器填充的对象的结构。如果缺少任何必填字段,或者如果提交的值无法转换为必填字段的类型,则整个对象将保留为空。
回答by Funka
I've been struggling with this same type of scenario and eventually came to realize that the underlying problem is that the MVC default model binder does not seem to work on EntitySet<T> fields, only List<T> fields. I did however find a simple workaround that seems acceptable. In my case, I have a Company entity that has one to many relationship to Contacts (my Linq-to-Sql EntitySet).
我一直在为这种相同类型的场景苦苦挣扎,最终意识到潜在的问题是 MVC 默认模型绑定器似乎不适用于 EntitySet<T> 字段,只能用于 List<T> 字段。然而,我确实找到了一个似乎可以接受的简单解决方法。就我而言,我有一个与联系人(我的 Linq-to-Sql EntitySet)有一对多关系的 Company 实体。
Since it seems that when I change my code from EntitySet<Contact> to List<Contact>, the MVC default model binder starts working as expected (even though the LTS isn't now), I figured I would provide an alternate, "aliased" property to MVC that is of type List<Contact>, and sure enough, this seems to work.
由于似乎当我将代码从 EntitySet<Contact> 更改为 List<Contact> 时,MVC 默认模型绑定器开始按预期工作(即使 LTS 现在不是),我想我会提供一个替代的“别名” " 类型为 List<Contact> 的 MVC 属性,果然,这似乎有效。
In my Company entity class:
在我的公司实体类中:
// This is what LINQ-to-SQL will use:
private EntitySet<Contact> _Contacts = new EntitySet<Contact>();
[Association(Storage="_Contacts", OtherKey="CompanyID", ThisKey="ID")]
public EntitySet<Contact> Contacts
{
get { return _Contacts; }
set { _Contacts.Assign(value); }
}
// This is what MVC default model binder (and my View) will use:
public List<Contact> MvcContacts
{
get { return _Contacts.ToList<Contact>(); }
set { _Contacts.AddRange(value); }
}
So now, in my View, I have the following:
所以现在,在我看来,我有以下几点:
<label>First Name*
<%= Html.TextBox("Company.MvcContacts[" + i + "].FirstName") %>
</label>
<label>Last Name*
<%= Html.TextBox("Company.MvcContacts[" + i + "].LastName") %>
</label>
Seems to work like a charm!
似乎很有魅力!
Best of luck! -Mike
祝你好运!-麦克风
回答by ATD
Make sure your models (and all nested models) are using properties (getters/setters) instead of fields. Apparently the default binder needs properties to function properly. I had a very similar situation that was fixed by changing the necessary fields to properties.
确保您的模型(以及所有嵌套模型)使用的是属性(getter/setter)而不是字段。显然,默认绑定器需要属性才能正常运行。我有一个非常相似的情况,通过将必要的字段更改为属性来解决。