ASP.NET MVC:DropDownListFor不選擇任何選項

[英]ASP.NET MVC: DropDownListFor doesn't select any option

I have this to populate a drop down list in an ASP.NET MVC view.

我有這個填充ASP.NET MVC視圖中的下拉列表。

<%= Html.DropDownListFor(model => model.Bikes,
      x => new SelectListItem {
               Text = x.Name,
               Value = Url.Action("Details", "Bike", new { bikeId = x.ID }),
               Selected = x.ID == Model.ID,
           })) %>

Debugging this I can see that the Selected property is set to true when it should be. But when the view is rendered, none of the options in the list is selected. I realize that this could be done with another overload of DropDownListFor but I really want to get this version working.


Any ideas?

2 个解决方案



The reason your selected value doesn't work is because you are using Urls as option values but specifying Model.ID in the Selected clause.


Try like this:


<%= Html.DropDownListFor(
    model => model.Bikes,
    new SelectList(Model.Bikes, "Id", "Name", Model.ID)

"Id" indicates the property that will be used as option value while "Name" indicates the property that will be used as option label.


If you want to preserve the Url.Action you could try:


<%= Html.DropDownListFor(
    model => model.Bikes,
    new SelectList(Model.Bikes.Select(x => new {
        Id = x.Id,
        Name = Url.Action("Details", "Bike", new { bikeId = x.ID })
    }), "Id", "Name", Model.ID)

You will notice that I've inverted the Name and Id as it seemed more logical to use the model Id as option value.



The reason this doesn't work is because you are binding to an IEnumerable (the first argument of the DropDownListFor helper). It should be a scalar property while you are using the same model.Bikes collection:


<%= Html.DropDownListFor(
    model => model.SelectedBikeValue,
        x => new SelectListItem {
                 Text = x.Name,
                 Value = Url.Action("Details", "Bike", new { bikeId = x.ID }),
                 Selected = x.ID == Model.ID,
)) %>

My remark about not using Urls as option values stands true.




I've had so many troubles with this concept. It especially manifests itself when you cannot pass it "name" property from the model that contains that property in an object, because such object name is automatically prepended to the name. This is crazy. After wasting many hours trying to figure this one out I just gave up and wrote my own Drop-Down extension which I publish here. It is very simple and it works just fine.


    public static MvcHtmlString SimpleDropDown(this HtmlHelper helper, object attributes, IEnumerable<SelectListItem> items, bool disabled = false)
        XElement e = new XElement("select",
            items.Select(a => {
                XElement option = new XElement("option", a.Text);
                option.SetAttributeValue("value", a.Value);
                if (a.Selected)
                    option.SetAttributeValue("selected", "selected");
                return option;

        if (attributes != null)
            Dictionary<string, string> values = (from x in attributes.GetType().GetProperties() select x).ToDictionary(x => x.Name, x => (x.GetGetMethod().Invoke(attributes, null) == null ? "" : x.GetGetMethod().Invoke(attributes, null).ToString()));
            foreach(var v in values)
                e.SetAttributeValue(v.Key, v.Value);

        if (disabled)
            e.SetAttributeValue("disabled", "");

        return new MvcHtmlString(e.ToString());

Also, I put flag disabled as an extra parameter, because if you want to bind to it via the standard anonymous list of attributes, it can be quite a hassle.


Below is an example of how I use it at the moment. I translate a dictionary into a list of SelectListItem, but it can be just a simple list.


@Html.SimpleDropDown(new { id="EOM", name = "EOM", @class = "topBox" }, Model.EOM.Select(x => new SelectListItem { Text = x.Value, Value = x.Key.ToString(), Selected = Model.EOM.Selected == x.Key }), !Model.EOM.Available)



粤ICP备14056181号  © 2014-2021