Reputation: 2882
I'm very new with MVC, so bear with me, but I can't seem to bind a value from a SelectList to an instance of the selected object during a postback in MVC 4.
Suppose I have to create a Teacher as a member of a School. I have a ViewModel class defined as such:
public class RegisterTeacherModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[Display(Name = "School")]
public School SelectedSchool { get; set; }
[ScaffoldColumn(false)]
public Guid UserId
{
get;
set;
}
public SelectList PossibleSchools
{
get;
private set;
}
public RegisterTeacherModel(IRepository<School> schoolRepo)
{
PossibleSchools = new SelectList(schoolRepo, "Id", "Name");
}
}
And my View:
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>RegisterTeacherModel</legend>
<div class="editor-label">
@Html.LabelFor(model => model.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.SelectedSchool)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.SelectedSchool, Model.PossibleSchools)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
And finally, my Controller method:
[HttpPost, ActionName("Create")]
public ActionResult CreateTeacher(RegisterTeacherModel teacherModel)
{
if (ModelState.IsValid)
{
try
{
...
}
}
}
But when I receive the RegisterTeacherModel object back in my Create method in the Controller, SelectedSchool is always null. I must be missing something in the way the model binder re-creates the object references on postback. Can anyone point me in the right direction?
Upvotes: 4
Views: 13965
Reputation: 543
I think you touched on it with your second post: Try pointing the initial code to Model.SelectedSchool.<IdProperty>
<div class="editor-field">
@Html.DropDownListFor(model => model.SelectedSchool.**<IdProperty>**, Model.PossibleSchools)
</div>
Upvotes: 3
Reputation: 2882
Well, I found a workaround. I still don't know if I'm missing something, but instead of using a School object in my ViewModel, I replaced it with the SelectedSchoolId as such:
public class RegisterTeacherModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[Display(Name = "School")]
public int SelectedSchoolId { get; set; }
...
}
And change my View dropdown to use this instead:
<div class="editor-field">
@Html.DropDownListFor(model => model.SelectedSchoolId, Model.PossibleSchools)
</div>
And then in my controller, when creating the real model objects I can simply pull the School object from the School repository and associate it with the real Teacher object.
Upvotes: 2