问题描述
我有一个名为AssetSearchModel的ViewModel,其属性类型为:List.
I have a ViewModel called AssetSearchModel with a property of type: List.
当我从ViewModel发布时,我的List的所有属性都成功绑定回了模型,除了以下内容:public DomainsDto DomainControl { get; set; }
定义在底部.
When I post from the ViewModel, all the properties of my List get binded back to the model successfully, except for this one: public DomainsDto DomainControl { get; set; }
which is defined at the bottom.
该domaincontrol具有几个属性,然后具有其自己的嵌套列表...没有设置任何属性,它们都为空
That domaincontrol has a couple of properties and then its own nested list... none of its properties get set, they are all null
public class AssetSearchModel
{
public List<SearchControlModel> SearchControls { get; set; }
public AssetSearchModel()
{
}
}
public class SearchControlModel
{
/// <summary>
/// Asset identifier.
/// </summary>
[DisplayName("AssetId ID")]
public int SearchOptionID { get; set; } // this gets bound ok
[DisplayName("Asset Customer ID")]
public int AssetCustomerID { get; set; } // this gets bound ok
[DisplayName("Portal ID")]
public int PortalID { get; set; } // this gets bound ok
[DisplayName("Calling Page")]
public string CallingPage { get; set; } // this gets bound ok
[DisplayName("Display Control")]
public string DisplayControl { get; set; } // this gets bound ok
[DisplayName("Display Text")]
public string DisplayText { get; set; } // this gets bound ok
public string ControlValue { get; set; } // this gets bound ok
[DisplayName("Search Table")]
public string SearchTable { get; set; } // this gets bound ok
[DisplayName("Search Column")]
public string SearchColumn { get; set; } // this gets bound ok
[DisplayName("Source Table")]
public string SourceTable { get; set; } // this gets bound ok
[DisplayName("Source Display Column")]
public string SourceDisplayColumn { get; set; } // this gets bound ok
[DisplayName("Source Value Column")]
public string SourceValueColumn { get; set; } // this gets bound ok
[DisplayName("SourceCustomFilter")]
public string SourceCustomFilter { get; set; } // this gets bound ok
[DisplayName("SortOrder")]
public int SortOrder { get; set; } // this gets bound ok
[DisplayName("DomainControl")]
public DomainsDto DomainControl { get; set; } // THIS DOES NOT BIND
public SearchControlModel()
{
}
}
public class DomainsDto
{
public int DomainMasterId; // this does not bind
public string DisplayName; // this does not bind
public List<DomainDto> Domains; // this does not bind
public DomainsDto()
{
}
}
[DataContract(Name = "Domain", Namespace = "http://www.comcom.com/")]
public class DomainDto
{
[DataMember]
public int DomainID { get; set; } // this does not bind
[DataMember]
public string DomainName { get; set; } // this does not bind
[DataMember]
public bool Checked { get; set; } // this does not bind
public DomainDto()
{
}
}
和我的观点:
@for (int y = 0; y < Model.SearchControls.Count; y++)
{
@Html.Label("Search option: " + Model.SearchControls[y].DisplayText)
<br />
@Html.HiddenFor(x => x.SearchControls[y].DisplayText)
@Html.HiddenFor(x => x.SearchControls[y].CallingPage)
@Html.HiddenFor(x => x.SearchControls[y].DisplayControl)
@Html.HiddenFor(x => x.SearchControls[y].SourceCustomFilter)
@Html.HiddenFor(x => x.SearchControls[y].SearchTable)
@Html.HiddenFor(x => x.SearchControls[y].SearchColumn)
@Html.HiddenFor(x => x.SearchControls[y].SourceValueColumn)
if (Model.SearchControls[y].DomainControl != null)
{
@Html.HiddenFor(x => x.SearchControls[y].DomainControl.DisplayName)
@Html.HiddenFor(x => x.SearchControls[y].DomainControl.DomainMasterId)
if (Model.SearchControls[y].DomainControl.Domains != null)
{
for (int z = 0; z < Model.SearchControls[y].DomainControl.Domains.Count; z++)
{
@Html.HiddenFor(x => x.SearchControls[y].DomainControl.Domains[z].DomainID)
@Html.HiddenFor(x => x.SearchControls[y].DomainControl.Domains[z].DomainName)
@Html.HiddenFor(x => x.SearchControls[y].DomainControl.Domains[z].Checked)
<br />
}
}
}
<br />
<br />
<hr width=100px />
}
html(对不起,单行显示,不能让我将其粘贴到其他位置)
the html (sorry for the single line, it wouldn't let me paste it in differently)
<label for="Search_option:_Product_Lines">Search option: Product Lines</label> <input id="SearchControls_1__DisplayText" name="SearchControls[1].DisplayText" type="hidden" value="Product Lines" /> <input id="SearchControls_1__CallingPage" name="SearchControls[1].CallingPage" type="hidden" value="AssetSearch" /> <input id="SearchControls_1__DisplayControl" name="SearchControls[1].DisplayControl" type="hidden" value="M" /> <input id="SearchControls_1__SourceCustomFilter" name="SearchControls[1].SourceCustomFilter" type="hidden" value="26" /> <input id="SearchControls_1__SearchTable" name="SearchControls[1].SearchTable" type="hidden" value="AssetDomainValue" /> <input id="SearchControls_1__SearchColumn" name="SearchControls[1].SearchColumn" type="hidden" value="Brand" /> <input id="SearchControls_1__SourceValueColumn" name="SearchControls[1].SourceValueColumn" type="hidden" value="DomainCodeValueID" /> <input id="SearchControls_1__DomainControl_DisplayName" name="SearchControls[1].DomainControl.DisplayName" type="hidden" value="Product Line" /> <input id="SearchControls_1__DomainControl_DomainMasterId" name="SearchControls[1].DomainControl.DomainMasterId" type="hidden" value="26" /> <input id="SearchControls_1__DomainControl_Domains_0__DomainID" name="SearchControls[1].DomainControl.Domains[0].DomainID" type="hidden" value="43680" /> <input id="SearchControls_1__DomainControl_Domains_0__DomainName" name="SearchControls[1].DomainControl.Domains[0].DomainName" type="hidden" value="YORK" /> <input id="SearchControls_1__DomainControl_Domains_0__Checked" name="SearchControls[1].DomainControl.Domains[0].Checked" type="hidden" value="False" /> <input id="SearchControls_1__DomainControl_Domains_1__DomainID" name="SearchControls[1].DomainControl.Domains[1].DomainID" type="hidden" value="43683" /> <input id="SearchControls_1__DomainControl_Domains_1__DomainName" name="SearchControls[1].DomainControl.Domains[1].DomainName" type="hidden" value="Johnson Controls" /> <input id="SearchControls_1__DomainControl_Domains_1__Checked" name="SearchControls[1].DomainControl.Domains[1].Checked" type="hidden" value="False" /> <br />
推荐答案
是的,模型绑定程序仅与,而不是字段.
Ah no, the model binder works only with properties only, not fields.
所以替换:
public class DomainsDto
{
public int DomainMasterId; // this does not bind
public string DisplayName; // this does not bind
public List<DomainDto> Domains; // this does not bind
public DomainsDto()
{
}
}
具有:
public class DomainsDto
{
public int DomainMasterId { get; set; } // this does bind
public string DisplayName { get; set; } // this does bind
public List<DomainDto> Domains { get; set; } // this does bind
public DomainsDto()
{
}
}
但是,实际上,在表单中填充隐藏字段的重点是什么?您已经在数据库中存储了这些东西.因此,只需放置一个包含ID的隐藏字段,该ID即可让您在数据驻留的任何位置去获取数据.我一直想知道人们为什么人们如此拼命地试图为MVC重新发明ViewState.这不是使用该模式的方式.您不再需要使用经典的WebForms.
But really, what's the whole point of stuffing a gazzilion of hidden fields in a form? You already have this stuff in your db or something. So simply put a hidden field containing an id that will allow you to go and fetch the data wherever this data resides. I've always wondered people why are people so desperately trying to reinvent the ViewState for MVC. It's just not the way this pattern is meant to be used. You are no longer doing classic WebForms.
在设计ASP.NET MVC视图时,这是一条应该驱使您的规则:
Here's a rule that should drive you when designing an ASP.NET MVC view:
- 用户应修改的任何字段都使用相应的输入字段(文本框,收音机,ddls和内容)
- 无论用户不应修改的任何字段,都不应出现在表单中.每个表单中最多应有一个隐藏字段,其中最多包含一个唯一的标识符,使您可以检索所需的信息
结论:使用视图模型.
因此,针对您的问题的实际解决方案是替换:
So the real solution to your problem is to replace:
[DisplayName("DomainControl")]
public DomainsDto DomainControl { get; set; } // THIS DOES NOT BIND
具有:
public int DomainControlId { get; set; }
,并在视图中对此ID使用单个隐藏字段.就是这样.
and using a single hidden field for this id in the view. That's it.
这篇关于MVC嵌套模型绑定仅部分起作用-我缺少什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!