Html.DropDownList AutoMapper problem
I am receiving this error:
The ViewData item that has the key 'DepartmentId' is of type 'System.Int32' but must be of type 'IEnumerable'.
with the following set up. I am not sure how to resolve it. The error is happening in the Model View code. This line: public void MapTo(Person domainModel). I am using AutoMapper to map ViewModel back to DomainModel (reversing the initial mapping of DomainModel to ViewModel).
Domain model (using LINQ to SQL, so this is a partial class):
public partial class Person { }
// Validation rules
public class Person_Validation
{
[HiddenInput(DisplayValue = false)]
[ScaffoldColumn(false)]
public object PersonId { get; set; }
[HiddenInput(DisplayValue = false)]
[ScaffoldColumn(false)]
public object DepartmentId { get; set; }
[DisplayName("Employee Name")]
[Required(ErrorMessage = "Employee Name is required")]
[StringLength(50, ErrorMessage = "Employee Name cannot be more than 50 characters")]
public object Name { get; set; }
[HiddenInput(DisplayValue = false)]
public object Active { get; set; }
[HiddenInput(DisplayValue = false)]
public object DateAdded { get; set; }
[HiddenInput(DisplayValue = false)]
public object DateDeleted { get; set; }
public object Department { get; set; }
}
This is my Model View:
public class PersonViewModel
{
public object PersonId { get; set; }
public object DepartmentId { get; set; }
public object Name { get; set; }
public object Active { get; set; }
public object DateAdded { get; set; }
public object DateDeleted { get; set; }
public object DepartmentName { get; set; }
//helper method
public void MapTo(Person domainModel)
{
Mapper.Map(this, domainModel);
}
}
Controller Class Code:
[HttpPost]
public ActionResult Edit(PersonViewModel viewModel)
{
var domainModel = new Person();
try
{
viewModel.MapTo(domainModel);
UpdateModel(domainModel);
_personRepository.Save();
return RedirectToAction("Index", "Person");
}
catch
{
return View(viewModel);
}
}
And my View HTML code:
<div class="editor-field">
<%: Html.DropDownLi开发者_C百科st("DepartmentId", (IEnumerable<SelectListItem>)ViewData["DepartmentList"])%>
<%: Html.ValidationMessageFor(model => model.DepartmentId) %>
</div>
you're not really following the best practices of developing a mvc application.
About the error:
the Html.DropDownList looks for Data of type IEnumerable<SelectListItem>
in the model but it finds an int
instead (DepartmentId
)
your ViewModel should not have the MapTo method, it breaks the single responsibility principle
in your action method you don't do any server side validation like:
if(!ModelState.IsValid)
{
//rebuild the viewmodel and return the view
}
catching everything in the action is also not necessary (and bad)
you do this in Global.asax Application_Error
instead
attributes like HiddenInput, ScaffoldColumn, Validation and anything else UI related should be on you ViewModel not in your domain model
for a good sample of using viewmodels & validation & mapping between entity <-> viewmodel I recommend you to look at the Samples solution from here
I did this sample and it's main purpose is to demonstrate the usage of ValueInjecter (mapping technology)
精彩评论