MVC 2 UpdateModel - how does it work?
I ask because I cannot get this code to work. I get an exception; "The model of type 'ITOC.WebUI.Models.Contract' could not be updated." Which does not seem very helpful.
** EDIT ** The above exception has been resolved because of a spelling mistake in the prefix, a classic "Magic String". Now the problem is that NOTHING GETS UPDATED! ** END EDIT **
I have to admit I am not clear how UpdateModel works, and I am not clear how the prefix works. The viewmodel is specified in the webpage;
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<ITOC.WebUI.Models.ContractViewModel>" %>
and the ViewModelClass is
public class ContractViewModel
{
//private ITOCEntities db = new ITOCEntities();
public Contract contract { get; set; }
public IList<ContractType> contractTypes { get; set; }
public IEnume开发者_JAVA技巧rable<SelectListItem> contractTypesSelectList
{
get
{
return this.contractTypes.Select(item => new SelectListItem
{
Text = item.ContractType1,
Value = item.ContractTypeId.ToString()
});
}
}
public Contact clientContact { get; set; }
public Contact contractAdministratorContact { get; set; }
public ContractViewModel()
{
using (var db = new ITOCEntities())
{
this.contractTypes = db.ContractTypes.ToList();
this.clientContact = new Contact();
this.contractAdministratorContact = new Contact();
this.clientContact.ContactTypeId =
db.ContactTypes.Where(x => x.ContactType1 == "Client").SingleOrDefault().ContactTypeId;
this.contractAdministratorContact.ContactTypeId =
db.ContactTypes.Where(x => x.ContactType1 == "CA").SingleOrDefault().ContactTypeId;
}
}
public ContractViewModel(int contractId)
{
using (var db = new ITOCEntities())
{
this.contractTypes = db.ContractTypes.ToList();
this.contract = db.Contracts.Where(x => x.ContractId == contractId).SingleOrDefault();
this.clientContact =
db.Contacts.Where(x => x.ContactId == this.contract.ClientContactId).SingleOrDefault();
this.contractAdministratorContact =
db.Contacts.Where(x => x.ContactId == this.contract.ContractAdministratorContactId).SingleOrDefault();
}
}
}
The Controller is;
[Authorize(Roles = "Inputter")]
[HttpPost]
public ActionResult Edit(int contractId, FormCollection formValues)
{
if (ModelState.IsValid)
{
using (var db = new ITOCEntities())
{
var contract = db.Contracts.Single(x => x.ContractId == contractId);
string letter = contract.ContractNo_Letter;
UpdateModel(contract, "Contracts");
var clientContact = db.Contacts.Single(x => x.ContactId == contract.ClientContactId);
UpdateModel(clientContact, "Contact");
var contractAdministrationContact =
db.Contacts.Single(x => x.ContactId == contract.ContractAdministratorContactId);
UpdateModel(contractAdministrationContact, "Contact");
db.SaveChanges();
}
return RedirectToAction("List");
}
return View();
}
try using TryUpdateModel
in an if/ else statement
if (TryUpdateModel(contract))
{
// save changes
}
else
{
// handle
}
TryUpdateModel
and UpdateModel
are intended to be used to merge an object with a posted model object.
Updates the specified model instance using values from the controller's current value provider.
- http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel.aspx
Try reading this post about these two methods.
try changing your Post Action Method to match your Model Object
[Authorize(Roles = "Inputter")]
[HttpPost]
public ActionResult Edit(ContractViewModel model)
{
//
}
if the id's on your form match to the properties of your ContractViewModel
object then model
will post with those values
To see what failed look at your Controller.ModelState entries. That will tell you what failed to bind. In my experience its usually a datatype mismatch.
1 and 3 of CubanX's answer don't really have any impact on ModelBinding errors. 2 can be ignored because if your getting a bind error you know its probably binding and probably don't have to worry about the Prefix.
A few things I noticed right off:
You don't have a ViewModel specified in your view. This line here means a View with no type specific model:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
Without seeing the view, we can't be sure what you're trying to bind to here, or even if you should be using a prefix.
You're not actually passing in the FormValues collection into UpdateModel. Try:
UpdateModel(contract, "Contract", formValues)
精彩评论