ShawnL
ShawnL

Reputation: 97

Saving updates to complex models with MVC3

I have a complex model class, of which only a few string columns should be (and can be) edited. When I open and edit a couple of these columns and save the form, the string columns are posted back just fine, but the other (array) columns are null -- this breaks the save to Entity Framework.

What's the proper way to go about this with MVC3 and EF?

Upvotes: 2

Views: 937

Answers (3)

Andiih
Andiih

Reputation: 12413

I think this is a common problem. There are a couple of approaches I use:

1) This is my recommended approach. Use a viewmodel which encompasses only the properties that you want to be edited. This can then be bound back directly as you are currently trying to do. The problem with this approach is that you then need to copy the properties from and to your EF objects. If the naming is consistent you may be able to use a dumb reflection copier. If they are not, or you need to walk a graph to copy them back, then I tend to end up putting that custom logic into the viewmodel class. (Which makes it more than a pure view model - but nothing other than the viewmodel and the view needs to be aware of its existence.)

2) Use modified binding. You can specify [Bind(Exclude="this,that,theother")] to stop certain properties being nulled out, and when the properties are scalar properties that you simply don't want to have on screen, use Html.HiddenFor(x=>x.myprop)

Another approach is

3) Custom Binders. You can register your own custom binder and engineer whatever you need. This isn't an approach I've used. but might work well.

The reason 1) is a much better approach than 2) (IMHO) is that 2) exposes your entire model for update via HTML POST. The MVC binder will bind changes to anything that fits, so a well crafted POST can do some unexpected things: traversing relationships you hadn't intended to expose and updating properties. The Viewmodel pattern on the other hand needs to have entities that only expose the fields the user interacts with so are safe to bind to.

Upvotes: 1

Adam Tuliper
Adam Tuliper

Reputation: 30152

Load the model from the databas then call TryUpdateModel(yourDbLoadedModel) to merge the values from your form to your model. You can also specify fields to include or exclude in this bind if you only want to include a few specific fields from the form - this would be recommended so someone can't hack your model by injecting form fields that aren't intended to exist such as a primary key value.

Upvotes: 2

toperux
toperux

Reputation: 1

You could bind your read only columns to hidden fields so that the model you get from post back will be complete though this could be a security problem depending on why you chose to hide the other columns

Upvotes: 0

Related Questions