ASP.NET MVC DropDownListFor not selecting value from model

后端 未结 5 676
梦毁少年i
梦毁少年i 2020-11-30 09:11

I\'m using ASP.NET MVC 3, and just ran into a \'gotcha\' using the DropDownListFor HTML Helper.

I do this in my Controller:

ViewBag.Ship         


        
相关标签:
5条回答
  • 2020-11-30 09:22

    This might be silly, but does adding it to a variable in your view do anything?

    var shippingTypes = ViewBag.ShippingTypes;
    
    @Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, shippingTypes)
    
    0 讨论(0)
  • 2020-11-30 09:22

    you can create dynamic viewdata instead of viewbag for each dropdownlist field for complex type. hope this will give you hint how to do that

          @if (Model.Exchange != null)
                                    {
                                        for (int i = 0; i < Model.Exchange.Count; i++)
                                        {
                                            <tr>
                                                @Html.HiddenFor(model => model.Exchange[i].companyExchangeDtlsId)
                                                <td>
                                                     
                                                    @Html.DropDownListFor(model => model.Exchange[i].categoryDetailsId, ViewData["Exchange" + i] as SelectList, " Select category", new { @id = "ddlexchange", @class = "form-control custom-form-control required" })
                                                    @Html.ValidationMessageFor(model => model.Exchange[i].categoryDetailsId, "", new { @class = "text-danger" })
                                                </td>
                                                <td>
                                                    @Html.TextAreaFor(model => model.Exchange[i].Address, new { @class = "form-control custom-form-control", @style = "margin:5px;display:inline" })
                                                
                                                    @Html.ValidationMessageFor(model => model.Exchange[i].Address, "", new { @class = "text-danger" })
                                                </td>
                                            </tr>
                                        }
    
                                    }

      ViewModel CompanyDetail = companyDetailService.GetCompanyDetails(id);
                   if (CompanyDetail.Exchange != null)
                    for (int i = 0; i < CompanyDetail.Exchange.Count; i++)
                    {
                        ViewData["Exchange" + i]= new SelectList(companyDetailService.GetComapnyExchange(), "categoryDetailsId", "LOV", CompanyDetail.Exchange[i].categoryDetailsId);
                    }

    0 讨论(0)
  • 2020-11-30 09:32

    There is an overloaded method for @html.DropdownList for to handle this. There is an alternative to set the selected value on the HTML Dropdown List.

    @Html.DropDownListFor(m => m.Section[b].State, 
                  new SelectList(Model.StatesDropdown, "value", "text", Model.Section[b].State))
    

    I was able to get the selected value from the model.

    "value", "text", Model.Section[b].State this section the above syntax adds the selected attribute to the value loaded from the Controller

    0 讨论(0)
  • 2020-11-30 09:34

    I was just hit by this limitation and figured out a simple workaround. Just defined extension method that internally generates SelectList with correct selected item.

    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString DropDownListForEx<TModel, TProperty>(
           this HtmlHelper<TModel> htmlHelper,
           Expression<Func<TModel, TProperty>> expression,
           IEnumerable<SelectListItem> selectList,
           object htmlAttributes = null)
        {
            var selectedValue = expression.Compile().Invoke(htmlHelper.ViewData.Model);
            var selectListCopy = new SelectList(selectList.ToList(), nameof(SelectListItem.Value), nameof(SelectListItem.Text), selectedValue);
    
            return htmlHelper.DropDownListFor(expression, selectListCopy, htmlAttributes);
        }
    }
    

    The best thing is that this extension can be used the same way as original DropDownListFor:

    @for(var i = 0; i < Model.Items.Count(); i++)
    {
       @Html.DropDownListForEx(x => x.Items[i].CountryId, Model.AllCountries)
    }
    
    0 讨论(0)
  • 2020-11-30 09:43

    The reason why this doesn't work is because of a limitation of the DropDownListFor helper: it is able to infer the selected value using the lambda expression passed as first argument only if this lambda expression is a simple property access expression. For example this doesn't work with array indexer access expressions which is your case because of the editor template.

    You basically have (excluding the editor template):

    @Html.DropDownListFor(
        m => m.ShippingTypes[i].RequiredShippingTypeId, 
        ViewBag.ShippingTypes as IEnumerable<SelectListItem>
    )
    

    The following is not supported: m => m.ShippingTypes[i].RequiredShippingTypeId. It works only with simple property access expressions but not with indexed collection access.

    The workaround you have found is the correct way to solve this problem, by explicitly passing the selected value when building the SelectList.

    0 讨论(0)
提交回复
热议问题