ASP.NET MVC published a non-LINQ model-mapped object
I have a page that is strongly typed for my User class. When it's loaded, I load it by id from the database and pass it to the view.
When the edit form is submitted, the object receives the controller method message exactly, with some other parameters. The object has its properties populated from the form, but the ID (which obviously isn't on the form) is not published.
Even when I manually set it to a code id and try to save my context, nothing happens in the database.
Here's a rough look at the code, with material removed for brevity.
public ActionResult MyProfile()
{
ViewData["Countries"] = new SelectList(userService.GetCountries(), "id", "name");
return View(userService.GetById(CurrentUser.id));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyProfile(MSD_AIDS_Images_Data.LINQRepositories.User user, string password2)
{
user.id = CurrentUser.id; //user id isn't posted, so need to reassign it
userService.SaveChanges();
}
I've written code like this a dozen times and it worked, what's wrong?
EDIT
When I debug a user object, its PropertyChanged and PropertyChanging properties are set to NULL
source to share
The custom object included in the MyProfile method is not associated with a LINQ context. You need to use explicit binding using UpdateModel like:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyProfile(int id, string password2)
{
MSD_AIDS_Images_Data.LINQRepositories.User user = <LINQ query to load user by id>;
UpdateModel(user); // updates the model with form values
userService.SaveChanges();
}
Note that you can implement a custom binder that does this prior to calling the controller method so that you can accept the User as a parameter, but I am assuming you did not.
source to share
I fixed the model binding issues with the Update Model overload, which allows you to specify which properties in the model you want to update:
string[] includeProperties = {"password", "firstname", "lastname", "email", "affiliation", "countryId"};
UpdateModel(user, includeProperties);
source to share