Vague
Vague

Reputation: 2280

MVC6 Dropdownlist of Countries

I am trying to use MVC6 Tag Helpers to create a dropdownlist of CountryCode and CountryName so that a user can select their country after registering. The relevant part of the view looks like this so far

<form asp-controller="Manage" asp-action="EditCountry" asp-route-returnurl="@ViewData["ReturnUrl"]">
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<select asp-for="CountryCode" asp-items="@Model.Countries"></select>

The relevant part of the viewmodel looks like this

[Display(Name = "Country")]
public string CountryCode { get; set; }
public IEnumerable<Country> Countries { get; set; }

A Country looks like this

public partial class Country
{
    [Key]
    public string CountryCode { get; set; }
    public string CountryName { get; set; }
    public virtual ICollection<ApplicationUser> Users { get; set; }
}

The controller returns a list of countries to the viewmodel

var model = new IndexViewModel
{
    CountryCode = user.CountryCode,
    Countries =_customersContext.Countries.OrderBy(c=>c.CountryName),
};
return View(model);

but in the view asp-items="@Model.Countries" has a squiggly Cannot convert Country to SelectListItem

Also I cannot find how in the form to specify CountryCode as the property to return and CountryName as the property to display.

Upvotes: 13

Views: 30298

Answers (3)

joacar
joacar

Reputation: 961

I have proposed an alternative way of doing this by extending the SelectTagHelper with some more attributes that can make this type of development more convenient. The issue is discussed here.

It is based on a class SelectListDescriptor that contain the list of items, the property to display the text and value field respectively. Then in the view one simple type

<select asp-descriptor="@ViewBag.CountryDescriptor"><option value="">-- Choose country</option<</select>.

The country descriptor is just new SelectListDescriptor(nameof(Country.CountryCode), nameof(Country.CountryName), countries). This avoid magic strings by utilizing the power of the `nameof-operator

Upvotes: 1

Siva Ragu
Siva Ragu

Reputation: 17

public class MyViewModel  //MODEL LAYER
    {
        public int CountryId { get; set; }

    public string CountryName { get; set; }
    public List<Employee> EmployeesList { get; set; }
}

public class Employee
{
    public int Id { get; set; }
    public string FullName { get; set; }
}

public IActionResult Contact1()  //CONTROLLER
        {

        MyViewModel N1 = new MyViewModel();
        List<Employee> N2 = new List<Employee>()
        {
            new Employee { Id=1,FullName="sivaragu" },
             new Employee { Id=2,FullName="siva" },
                  new Employee { Id=3,FullName="SENTHIL" }
        };

        ViewBag.MovieType = N2;
        return View();            
    }

CSHTML(MVC6)

<select  asp-for="CountryId" asp-items="@(new SelectList(@ViewBag.MovieType,"Id","FullName") )">    
    </select>

Upvotes: 2

Vlince
Vlince

Reputation: 6011

The way I make my dropdowns is somewhat similar except that in my ViewModel, my property is of type SelectList instead of an IEnumerable<>.

public class HomeViewModel
{
    public string CountryCode { get; set; }
    public SelectList CountryList { get; set; }
}

Then in the controller I get the data and convert it to an anonymous list with two properties “Id” and “Value”.

In turn, I create a new SelectList() passing in the anonymous list specifying what is the dataValueField and what is the dataTextField.

public IActionResult Index()
{
    var countries = _customersContext.Countries.OrderBy(c => c.CountryName).Select(x => new { Id = x.Code, Value = x.Name });

    var model = new HomeViewModel();
    model.CountryList = new SelectList(countries, "Id", "Value");

    return View(model);
}

Finally, in the View:

<div class="form-group">
    <label asp-for="CountryCode" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <select asp-for="CountryCode" asp-items="@Model.CountryList"></select>
    </div>
</div>

Upvotes: 47

Related Questions