Reputation: 4249
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
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