I have an Action method in an ASP.NET MVC Controller class that handles form posts from a fairly basic ‘create/edit a user’ page. I’m new to MVC so I’ve been following code samples from various Microsoft tutorials, this is how the method looks currently:
[AcceptVerbs(HttpVerbs.Post)] public ViewResult Save([Bind(Prefix = 'ServiceUser')]ServiceUser SUser) { if (SUser.ServiceUserId == 0) //new service user ServiceUserHelper.AddServiceUser(SUser); else //update to existing service user { using (ProjectDataContext db = DatabaseHelper.CreateContext()) { this.UpdateModel(db.ServiceUsers.Single(su => su.ServiceUserId == SUser.ServiceUserId), 'ServiceUser'); db.SubmitChanges(); } } //return a confirmation view }
This works fine; however my instincts tell me that the ‘ProjectDataContext…’ code doesn’t belong in the controller. If I were to move the Update functionality to an other class (in the way I have done with the Insert method), I’d lose the convenience of the Controller’s UpdateModel() method, and probably end up having to do something quite verbose to read the existing entity, update its properties, and submit the changes.
So my question is, what is the best way to achieve this? Is there a method similar to UpdateModel() somewhere in LINQ that can merge two entities of the same type together before submitting?
Thanks.
Most people will suggest using the ‘Repository Pattern’ to move that data access code out of the controller (and to enable unit testing with mock objects instead of the real database).
Here are some places to read more:
Edit:
I highly recommend reading the entire Scott Guthrie chapter linked above. It has a wealth of good advice in it. That said, here are some relevant examples (excepted from the chapter)…
First, I generally like to have different actions for ‘Update’ vs. ‘Add’. Even if they are the same View to render the form, it generally feels cleaner to have different URLs for POSTing an edit vs POSTing a new record. So, here is what the repository pattern in use looks like in a controller’s update action:
Here is the ‘Add’ example:
For both examples above, the DinnerRepository looks like this: