3

我有一个名为 AssetSearchModel 的 ViewModel,其属性类型为:List。

当我从 ViewModel 发布时,我的 List 的所有属性都成功绑定回模型,除了这个:public DomainsDto DomainControl { get; set; }在底部定义。

该域控制有几个属性,然后是它自己的嵌套列表......它的任何属性都没有设置,它们都是空的

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(对不起单行,它不会让我以不同的方式粘贴它)

<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 />
4

1 回答 1

11

啊,不,模型绑定器仅适用于属性,而不适用于字段

所以替换:

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()
    {

    }
}

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.

Here's a rule that should drive you when designing an ASP.NET MVC view:

  • whatever fields the user is supposed to modify use corresponding input fields (textboxes, radios, ddls and stuff)
  • whatever fields the user is not supposed to modify, it shouldn't appear in the form. You should have at maximum one hidden field per form containing at maximum an unique identifier allowing you to retrieve the information you need

Conclusion: use view models.

So the real solution to your problem is to replace:

[DisplayName("DomainControl")]
public DomainsDto DomainControl { get; set; } // THIS DOES NOT BIND

with:

public int DomainControlId { get; set; }

and using a single hidden field for this id in the view. That's it.

于 2012-07-20T19:26:41.730 回答