Tschareck
Tschareck

Reputation: 4249

Select from Dropdown in View and pass back to Controller

I have a model like this:

public class UserProfile
{
    public Guid ID { get; set; }
    public string DisplayName { get; set; }
    public Language PreferredLang { get; set; }
}
public class Language
{
    [Key]
    public int LanguageID { get; set; }
    public string LanguageCode { get; set; }
    public string DisplayName { get; set; }
}

And I want to be able to select preferred language from dropdown.

In controller I get list of languages and put it in ViewBag. In view I load this list. Then i want to save selection.

My controller:

public ActionResult EditProfile()
{
    List<Language> langauges =  Logic.GetAllLanguages();
    ViewBag.Languages = langauges;
    UserProfile profile = GetUserProfile();
    return View(profile);
}

An my view:

@using (Html.BeginForm()) {

    @Html.EditorFor(model => model.DisplayName)
    <div class="display-field">
        @Html.DropDownListFor(x => x.PreferredLang, new SelectList(ViewBag.Languages, "LanguageID", "DisplayName") as SelectList)

    </div>
    <input type="submit" value="Save" />
}

When user clicks "Save", element object passed to controller has DisplayName, but PreferredLang is always null. How can I pass Language back to controller?

[HttpPost]
public ActionResult EditProfile(UserProfile element)
{
    //save element
}

Upvotes: 1

Views: 4466

Answers (1)

Zabavsky
Zabavsky

Reputation: 13640

Create a ViewModel with following properties:

UserProfileViewModel

public class UserProfileViewModel
{
    public Guid ID { get; set; }
    public string DisplayName { get; set; }
    public int PreferredLangID { get; set; }
    public IEnumerable<Language> PreferredLanguages { get; set; }
}

View

@using (Html.BeginForm())
{
    @Html.HiddenFor(model => model.ID)
    @Html.EditorFor(model => model.DisplayName)
    <div class="display-field">
        @Html.DropDownListFor(x => x.PreferredLangID, new SelectList(Model.PreferredLanguages, "LanguageID", "DisplayName"))
    </div>
    <input type="submit" value="Save" />
}

Controller

public ActionResult EditProfile()
{
    List<Language> languages = Logic.GetAllLanguages();
    UserProfile profile = GetUserProfile();
    var viewModel = new UserProfileViewModel
        {
            ID = profile.ID,
            DisplayName = profile.DisplayName,
            PreferredLanguages = languages
        };
    return View(viewModel);
}

[HttpPost]
public ActionResult EditProfile(UserProfileViewModel viewModel)
{
    List<Language> languages = Logic.GetAllLanguages();
    if(ModelState.IsValid)
    {
        var userProfile = new UserProfile
            {
                ID = viewModel.ID,
                DisplayName = viewModel.DisplayName,
                PreferredLang = languages.FirstOrDefault(l => l.LanguageID == viewModel.PreferredLangID)
            };
        //save element
    }
    viewModel.PreferredLanguages = languages;
    return View(viewModel);
}

Upvotes: 3

Related Questions