简体   繁体   中英

Populating @Html.DropDownListFor — OK from hard-coded values, error from database

We are populating drop down lists on our forms, built in C# ASP.NET MVC 4 (sometimes 5). Thanks to SOF, I built a temporary list like so:

/// <summary>
/// Generate a list of countries.
/// </summary>
/// <returns>List(SelectListItem)</returns>
/// <remarks>Values are from ISO 3166-1 alpha-3</remarks>
public static List<SelectListItem> Countries()
{
    List<SelectListItem> items = new List<SelectListItem>();

    items.Add(new SelectListItem { Text = "United States of America", Value = "USA", Selected = true });
    items.Add(new SelectListItem { Text = "Australia", Value = "AUS" });
    items.Add(new SelectListItem { Text = "Canada", Value = "CAN" });
    items.Add(new SelectListItem { Text = "Mexico", Value = "MEX" });
    items.Add(new SelectListItem { Text = "United Kingdom", Value = "GBR" });

    return items;
}

Then passed this into the ViewBag:

ViewBag.CountryList = SelectLists.Countries();

and rendered it as:

@Html.DropDownListFor( model=>model.country_code, 
    (List<SelectListItem>)ViewBag.CountryList )

This part all worked just fine.

Now the team is implementing code to retrieve the lookups from the database instead of from mock data, and things are not fine. Our business object method accepts a lookup type, in this case "Country", and should return a List<SelectListItem> :

Controller:

List<SelectListItem> countryList = GetLookupData( "Country" );
ViewBag.CountryList = countryList;

Model:

public static List<SelectListItem> GetLookupData(string lookupType)
{
    MPPEntities dbContext = new MPPEntities();
    var query = (from c in dbContext.SystemLookups
                    where c.lookup_type == lookupType
                    orderby c.order_by
                    select new SelectListItem { Text = c.name, Value = c.value })
                    .ToList<SelectListItem>();

    return (List<SelectListItem>)query;
}

While we are debugging the LINQ, query contains the correct data. But when the debugger returns to the controller, countryList fails as "Could not evaluate expression." And then of course the view itself fails.

Based on the observation that the mock list worked and that the real list contains the correct data, I deduce that the point of failure is in the conversion from a generic collection to List<SelectListItem> . What is the right way to convert the list type?

ETA: The error in the CSHTML file is: "RuntimeBinderInternalCompilerException was unhandled by user code." And this is with the fewer casts as recommended below.

You seem to make many useless castings...

Could you try

public static List<SelectListItem> GetLookupData(string lookupType)
    {
       MPPEntities dbContext = new MPPEntities();
       return (from c in dbContext.SystemLookups
                    where c.lookup_type == lookupType
                    orderby c.order_by
                    select new SelectListItem { Text = c.name, Value = c.value })
                    .ToList();
    }

Could you try, in your view

@{
  var contryCodes = (IEnumerable<SelectListItem>)ViewBag.CountryList;
}

@Html.DropDownListFor( model=>model.country_code, 
    countryCodes )

cause it looks like a problem with dynamic (ViewBag)...

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