ASP.NET MVC DropDownListFor不选择从模型值ASP.NET MVC Drop

2019-06-01 03:19发布

我使用ASP.NET MVC 3,刚跑进使用一个“疑难杂症” DropDownListFor HTML辅助。

我这样做,在我的控制器:

ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();

GetShippingTypes方法:

public SelectList GetShippingTypes()
{
    List<ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes();

    return new SelectList(shippingTypes, "Id", "Name");
}

我把它的原因ViewBag而不是在模型(我强类型为每个视图模型),是我有呈现使用EditorTemplate,这也需要访问ShippingTypes选择列表项的集合。

否则,我需要遍历整个集合,并分配一个ShippingTypes属性即可。

到现在为止还挺好。

在我看来,我这样做:

@Html.DropDownListFor(m => m.RequiredShippingTypeId, ViewBag.ShippingTypes as SelectList)

RequiredShippingTypeId是类型Int32

什么情况是,该值RequiredShippingTypeId 没有在下拉选择向下。

我碰到这个传来: http://web.archive.org/web/20090628135923/http://blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx

他认为,MVC将查找从选定值ViewData ,当选择列表是从ViewData 。 我不知道这样的话了,因为博客帖子是旧的,他在谈论MVC 1个测试版。

解决该问题的解决方法是这样的:

@Html.DropDownListFor(m => m.RequiredShippingTypeId, new SelectList(ViewBag.ShippingTypes as IEnumerable<SelectListItem>, "Value", "Text", Model.RequiredShippingTypeId.ToString()))

我试着不去ToStringRequiredShippingTypeId底,这给了我同样的行为像以前一样:没有选择的项目。

我想这是一个数据类型的问题。 最终,HTML帮助是比较字符串(在选择列表) Int32 (从RequiredShippingTypeId )。

但为什么它不把选择列表的在工作时ViewBag :当将其添加到模型时,而这样做的视图中完美的作品-

@Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, Model.ShippingTypes)

Answer 1:

为什么这不工作的原因是因为的限制DropDownListFor助手:它能够推断使用仅如果 lambda表达式是一个简单的属性访问表达式第一个参数传递lambda表达式选择的值。 例如,这不符合数组索引访问表达式这是因为编辑器模板的工作你的情况。

你基本上(不包括编辑模板):

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

以下是不支持: m => m.ShippingTypes[i].RequiredShippingTypeId 。 它仅适用于简单的属性访问表达式,但不与索引集合访问。

你已经找到了解决方法是解决这一问题,通过建立明确时,通过选择价值的正确方法SelectList



Answer 2:

这可能是愚蠢的,但它添加到您的视图做任何一个变量?

var shippingTypes = ViewBag.ShippingTypes;

@Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, shippingTypes)


Answer 3:

你可以为复杂类型的每个下拉列表字段创建动态可视数据,而不是viewbag。 希望这会给你暗示该怎么做

  @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); } 



Answer 4:

我只是通过这一限制击中,想出了一个简单的解决方法。 刚刚定义的在内部产生的扩展方法SelectList与正确选择的项目。

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);
    }
}

最好的事情是,这个扩展可以使用的方式同原DropDownListFor

@for(var i = 0; i < Model.Items.Count(); i++)
{
   @Html.DropDownListForEx(x => x.Items[i].CountryId, Model.AllCountries)
}


Answer 5:

没有为@ html.DropdownList重载方法来处理这个问题。 还有就是要设置的HTML下拉列表中选择的值替代。

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

我能得到从模型中选择的值。

"value", "text", Model.Section[b].State本节中的上述语法将所选属性从控制器加载的值



文章来源: ASP.NET MVC DropDownListFor not selecting value from model