Reputation: 6477
I am using MVC3, Razor, C#, .NET4, EF5.
I have a number of situations where I am editing the domain model directly, and yes I realise that I should be using View Models :) However for the short term I am hoping I can get a solution to my problem whereby I am getting nulls being saved to the DB, where those fields are not specified as Hidden Fields in the forms. I realise this is to do with the Model Binding behaviour.
My Edit Action:
public ActionResult Edit(int id)
{
StdOrg myOrg = db.StdOrg.Single(s => s.Id == id);
return View(myOrg);
}
Lets assume my View has 5 fields on it:
Name
Address1
Address2
Address3
Address4
Now for my Post Edit Action:
[HttpPost]
public ActionResult Edit(StdOrg myOrg)
{
if (ModelState.IsValid)
{
db.StdOrg.Attach(myOrg);
db.ObjectStateManager.ChangeObjectState(myOrg, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(myOrg);
}
Now my Table record has 10 columns in it, and columns 6-10 has values.
Name
Address1
Address2
Address3
Address4
Terms
EmployeeNo
Code
Active
SetUpDate
When I save the form, columns 6-10 ie Terms etc. get set to null. Now I realise this is due to the fact that I am not specifying them as hidden fields in my View and therefore MVC Model Binding is assuming these are null.
Is there a practical way around this, rather than specifying all columns in the form which I would rather not do for security reasons.
Many thanks in advance.
EDIT
My attempt which does not seem to work:
[HttpPost]
public ActionResult Edit([Bind(Include = "Id,Name,Name,Address1,Address2,Address3,Address4")] StdOrg myOrg)
Thoughts.... ???
IN CONCLUSION
For those interested I ended up using the "Value Injector" which is the other "Automapper" for which I wrote a simple matching routine to prevent nulls being set, and also to exclude navigation properties as well. Very useful Mapper.
One still really needs to implement ViewModels since these seem the only way to identify which of the classes properties are in the View, unless one can get Bind attribute working which I could not. Otherwise even with a mapper one cannot reset a View field to null, since the mapper will ensure that it is ignored !! It cannot tell between View Properties and others in the domain class, as far as I can see.
Upvotes: 0
Views: 889
Reputation: 1263
Despite putting Exclude stuff:
[Bind(Exclude = "PropertyName,PropertyType")]
public class Filter {
public string PropertyName { get; set; }
public Type PropertyType { get; set; }
public string From { get; set; }
public string To { get; set; }
public string Match { get; set; }
}
those properties seem to be ovewritten with NULL, when I call this method from model (note: PropertyName and PropertyType are not and must not be present in markup! They are filled once in the code, before making markup)
[HttpPost]
public virtual PartialViewResult LoadFiltered(string entityType, IDictionary<string, Filter> filters)
And when no elements selected (all filters are disabled in interface) - I get two elements, having "controller" and "action" as keys. What the... ??
Upvotes: 0
Reputation: 2824
Try using the BindAttribute, you can simply exclude or include the fields for that particular action (which is always good practice, someone could manipulate the ID field on the POST and modify a different value).
See this question for an example
Upvotes: 1