简体   繁体   中英

Html.DropDownListFor doesn't select correct value

Generating a Selectlist (IEnumerable) from a XML file with countries, using this with DropDownListFor does not set the selected value supplied in the Model??

public static IEnumerable<SelectListItem> CountrySelectList()
    {
        var sRetVal = new List<SelectListItem>();
        string CachKey = "MVCXMLCountryList" + GetCulture();
        if (HttpContext.Current.Cache[CachKey] == null | 1 == 1)
        {
            string xmlFile = Path.Combine(HttpContext.Current.Server.MapPath("~"),      "Countries.xml");

            XmlDocument Doc = new XmlDocument();
            Doc.Load(xmlFile);
            foreach (XmlNode Node in    Doc.SelectNodes(String.Format("//Countries/language[@iso=\"{0}\"]/country", GetCulture())))
            {
                var tmpSelect = new SelectListItem();
                tmpSelect.Value = Node.Attributes["iso2"].InnerText.ToString();
                tmpSelect.Text = Node.Attributes["name"].InnerText;
                tmpSelect.Selected = false;
                sRetVal.Add(tmpSelect);
            }
            sRetVal.Sort(CountrySort);
            var prioritet = new string[] {"de","fo","se","no","dk"};
            switch (GetCulture())
            {
                case "dk": prioritet = new string[] {"de","fo","se","no","dk"}; break;
                default: prioritet = new string[] { "de", "se", "no", "dk", "gb" }; break;
            }

                foreach (string Country in (string[])prioritet)
                {
                    selectedCountry = Country;
                    var tmpSel = sRetVal.Find(FindCurrentSelected);
                    sRetVal.RemoveAt(sRetVal.FindIndex(FindCurrentSelected));
                    sRetVal.Insert(0, tmpSel);
                }
                //sRetVal[10].Selected = true;
            HttpContext.Current.Cache[CachKey] = sRetVal;
        }
        else
        {
            sRetVal = (List<SelectListItem>)HttpContext.Current.Cache[CachKey];
        }
        return (IEnumerable<SelectListItem>) sRetVal;
    }

Have tried both:

@Html.DropDownListFor(model => model.Country, new SelectList(CommonHelpers.CountrySelectList(), "Value", "Text", Model.Country), "---Select---")

and

@Html.DropDownListFor(model => model.Country, CommonHelpers.CountrySelectList(), "---Select---")

any idears?

The model property (Country) and the explicitly passed in SelectList are required to have different names to hook up the selected item. When there is no selected value provided, browsers default to the first element in the SelectList. This is a known limitation of the DropDownList helper. I'm finishing a DDL tutorial. You can get the completed code at http://code.msdn.microsoft.com/Using-the-DropDownList-67f9367d Shoot me an email and I'll send you the tutorial.Rick.Anderson[at]microsoft.com

You need to pass "Country" value to your method then check for selected value

public static IEnumerable<SelectListItem> CountrySelectList(string countryId)
{
    var sRetVal = new List<SelectListItem>();
    // .......................         
    foreach (XmlNode Node in Doc.SelectNodes(String.Format("//Countries/language[@iso=\"{0}\"]/country", GetCulture())))
    {
        var tmpSelect = new SelectListItem();
        tmpSelect.Value = Node.Attributes["iso2"].InnerText.ToString();
        tmpSelect.Text = Node.Attributes["name"].InnerText;
        // Check for selected value
        tmpSelect.Selected = string.Equals(tmpSelect.Value, countryId);
        sRetVal.Add(tmpSelect);
    }
    //...................
    return (IEnumerable<SelectListItem>)sRetVal;
}

Or just make new helper to do this for you. Something like this:

public static IEnumerable<SelectListItem> SetSelected(this IEnumerable<SelectListItem> selectList, string selectedValue)
{
    var newList = new List<SelectListItem>();
    var oldList = selectList.ToList();
    for (var i = 0; i < oldList.Count; i++)
    {
        var item = oldList[i];
        item.Selected = string.Equals(item.Value, selectedValue, StringComparison.CurrentCultureIgnoreCase);
        newList.Insert(i, item);
    }
    return newList;
}

And here is the usage :

@Html.DropDownListFor(model => model.Country, CommonHelpers.CountrySelectList().SetSelected(model.Country), "---Select---")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM