MVC 2 DropDownList在List的情况下不选择值

Mic*_*ong 3 c# model-view-controller asp.net-mvc drop-down-menu

我正在使用ASP.Net MVC 2并且无法正确绑定DropDownList.

我使用强类型的ViewModel和HTML.DropDownListFor语句在我的视图中创建下拉列表.该语句在"正常"场景中工作正常,我只是将DropDown绑定到ViewModel中的一个简单字段.当我的ViewModel包含多个对象的List(数组)时,我在使用这个场景时遇到问题,我想让每个对象中的一个字段绑定到(单独的)DropDown.在这种情况下,DropDown不会获得正确的初始值.

例如,我们有一个人可以拥有多个地址的情况.每个地址包括街道,城市和州.我希望状态显示为DropDown.我的模型是:

public class PersonModel : CommonViewModel
{
    public IList<SelectListItem> AvailableStates { get; set; }

    public string Name { get; set; }

    public IList<AddressModel> Addresses { get; set; }

    public PersonModel()
    {
        AvailableStates = GenerateStates();
    }

    private IList<SelectListItem> GenerateStates()
    {
        List<SelectListItem> items = new List<SelectListItem>();
        items.Add(new SelectListItem() { Text = "WA", Value = "WA" });
        items.Add(new SelectListItem() { Text = "NY", Value = "NY" });
        items.Add(new SelectListItem() { Text = "IH", Value = "IH" });
        items.Add(new SelectListItem() { Text = "FL", Value = "FL" });
        items.Add(new SelectListItem() { Text = "CA", Value = "CA" });

        return items;
    }
}

public class AddressModel
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在在我的视图中我想使用类似的东西:

<% using (Html.BeginForm("SubmitPersonDetails", "Home", new { actionMode = "Person"}, FormMethod.Post, new { id = "SubmitPersonForm" }))
   {%>
    <div class="formrow longinput">
    <%= Html.LabelFor(person => person.Name)%>
    <%= Html.TextBoxFor(person => person.Name)%>
</div>
<h4>Addresses</h4>
<% for (int i = 0; i < Model.Addresses.Count; i++) { %>
<div class="formrow">
<%= Html.TextBoxFor(person => person.Addresses[i].Street)%>
<%= Html.TextBoxFor(person => person.Addresses[i].City)%>
<%--<%= Html.TextBoxFor(person => person.Addresses[i].State)%>--%>
<%= Html.DropDownListFor(person => person.Addresses[i].State, Model.AvailableStates) %>
</div>
<% } %>
 <input class="button primary" type="submit" value="Submit" name="Submit" />
<% } %>
Run Code Online (Sandbox Code Playgroud)

对于Textboxes,这工作正常(如果我只使用State的文本框,请参阅注释掉的位).DropDown是正确生成但未设置为正确的值.如果我在DropDowns中选择一个值并提交表单,则将正确的值放回到我的模型中.

我还尝试将Address部分放在UserControl中,然后再渲染几次.如果我使用Html.RenderPartial渲染UserControl,则在DropDOwn中设置正确的值,但在Postback上我的模型未正确填充.如果我使用EditorFor渲染UserControl,我会遇到与上面代码相​​同的问题:DropDown没有获得正确的初始值,但在Postback上我确实得到了我的模型中设置的选定值.

我尝试的另一件事是使地址不是一个列表,而是硬编码我的视图模型中的几个地址(属性:Address1,Address2,Address3),然后使用:<%= Html.DropDownListFor(person => person.Address1.State,Model .AvailableStates)%>在这种情况下,DropDown会获得正确的值.显然,由于缺乏灵活性,我不想使用此解决方法.

我究竟做错了什么?我是MVC的新手所以也许我的整个方法都是错的?

Dar*_*rov 8

这是DropDownListFor助手的限制,无法从复杂的lambda表达式中提取值,例如您正在使用的表达式(包含数组索引访问的lambda表达式).一种可能的解决方法如下:

<%= Html.DropDownListFor(
    person => person.Addresses[i].State, 
    new SelectList(
        Model.AvailableStates, 
        "Text", 
        "Value", 
        Model.Addresses[i].State
    )
) %>
Run Code Online (Sandbox Code Playgroud)

它有点难看,因为我们现在在SelectList构造函数中传递相同的值,但这次DropDownListFor帮助器将能够正确设置相应的选项.

  • 注意`dataValueField`参数是第二个,`dataTextField`参数是第三个,所以你可能想要切换"Text"和"Value". (3认同)
  • 谢谢,这似乎工作正常.正如你所说:也许不像我希望的那样优雅,但绝对可以接受. (2认同)