I have a 2 Models:
public class Person
{
public Guid ID { get; set; }
public string Name { get; set;}
}
public class Event
{
public Guid ID { get; set; }
public string EventName { get; set; }
public virtual Person Owner { get; set; }
}
I have a ViewModel:
public class EventViewModel
{
public EventViewModel() { }
public Event EventToEdit { get; set; }
public SelectList People { get; set; }
}
I have my Controller:
public ViewResult Create()
{
var eve = new Event();
var vm = new EventViewModel
{
EventToEdit = eve,
People = GetPeopleList(true, eve)
}
return View(vm)
}
I have my View:
@Html.DropDownListFor(x => x.EventToEdit.Owner, Model.People)
Obviously they are cut down for reading purposes.
When I submit my view, and hit a breakpoint in the ActionResult Create
- It doesn't have a value for Owner (the list is populated correctly)
- The ViewModel People is also null
The point of using a ViewModel is carry information to and from the view to the controller so firstly why is People null.
Secondly and most importantly, why on earth is Owner not getting populated properly. There are people to choose from. Event name will be passed back through the model so the ViewModel is working somewhat...
Thanks,
First, it should be:
@Html.DropDownListFor(x => x.EventToEdit.Owner.ID, Model.People)
So that Model.People was something like this:
new SelectList(source, "ID", "Name", source.ID)
Check the HTML to see what is placed in the value for the option elements in the HTML, I suspect that MVC cannot cast this value into EventToEdit.Owner
as I think it can only handle strings and integers though you could write a custom modelbinder for this if you need to use another datatype.
ASP.Net will not post back the values used to populate the drop down list for efficiency (see here).
Personally I find the drop down lists not very helpful, they're designed to show data directly from the database, so you'd be able to re-query to get the SelectList values in the controller as needed and link them back to this re-queried list by placing simple IDs in the option values.
Taking karaxuna's answer:
First, it should be:
@Html.DropDownListFor(x => x.EventToEdit.Owner.ID, Model.People)
So that Model.People was something like this:
new SelectList(source, "ID", "Name", source.ID)
And expanding on that:
new ViewModel:
public class EventViewModel
{
public EventViewModel() { }
public Event EventToEdit { get; set; }
public SelectList People { get; set; }
public Guid SelectedPerson { get; set; }
}
View Binding:
@Html.DropDownListFor(x => x.SelectedPerson, Model.People)
Then in the Controller:
var person = _repository.People.FirstOrDefault(x => x.ID.CompareTo(vm.SelectedPerson) == 0);
vm.EventToEdit.Person = person;
_repository.SaveEvent(vm.EventToEdit);
I write this answer for clarity, anyone who comes searching might prefer to see a complete page.