Trying to get UpdateModel to work for my User. The User class has basic string properties like CompanyName, FirstName, LastName, etc so nothing exotic.
Here is the header for my view:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Public.Master" Inherits="System.Web.Mvc.ViewPage<User>" %>
After they submit, in my controller, the code looks like this:
[HttpPost]
public ActionResult Edit(string id, FormCollection collection)
{
try
{
User myUser = db.Get<IUserRepository>().Get(id);
UpdateModel(myUser);
db.Update(myUser);
return RedirectToAction("Index", "Home");
}
catch
{
return View();
}
}
The values past into FormCollection have the values like:
[0] "FirstName" string
[1] "LastName" string
[2] "Email" string
Here is my开发者_C百科 UserModelBinder (took out some error checking code) which seems to be the source of the problem:
public class UserModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
IPrincipal p = controllerContext.HttpContext.User;
User u = db.Get(p.Identity.Name);
return u;
}
}
while the myUser I get from the database has all its original values, the UpdateModel for my controller never actually makes any changes. I have read problems people have with ViewModels and which prefix to use, but I am just passing in the regular database object.
The strange thing is that this User edit is for my "Public" area and I already have a User edit for the Admin area which lets the administrator change extra Properties. The "Admin" area User edit is working fine, but the "Public" area for User edit isn't even though the code is almost identical.
Update:
This turned out to be a custom ModelBinding problem and by changing my UserModelBinding to derive from DefaultModelBinder and adding into my BindModel method:
if (bindingContext.Model != null)
return base.BindModel(controllerContext, bindingContext);
Everything seems to work.
Try this instead
public ActionResult Edit(User thisUser)
Id will need to come from a hidden field maybe.
Also you will need to ensure your field names match the User property names.
You shouldn't need to do anything more as the object should have the values within it.
If this is not helpful then let me know and I'll remove this answer
edit
This is one of my update methods
[HttpPost]
public ActionResult EditCustomer(Customer customer)
{
//ensure that the model is valid and return the errors back to the view if not.
if (!ModelState.IsValid)
return View(customer);
//locate the customer in the database and update the model with the views model.
Customer thisCustomer = customerRepository.Single(x => x.CustomerID == customer.CustomerID);
if (TryUpdateModel<Customer>(thisCustomer))
customerRepository.SaveAll();
else
return View(customer);
//return to the index page if complete
return RedirectToAction("index");
}
edit 2
my custom model binder
public class CustomContactUsBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ContactFormViewModel contactFormViewModel = bindingContext.Model as ContactFormViewModel;
if (!String.IsNullOrEmpty(contactFormViewModel.Name))
if (contactFormViewModel.Name.Length > 10)
bindingContext.ModelState.AddModelError("Name", "Name is too long. Must be less than 10 characters.");
base.OnModelUpdated(controllerContext, bindingContext);
}
}
This blog post sounds like it solves your exact problem:
UpdateModel(user, "User");
Since it seems the data you want to bind to is prefixed by the viewmodel name.
精彩评论