MVC controller actions - handle POST and GET without duplicate code

I work on this MVC 3 Razor app and usually use view models for my views.

A fair number of models of my presentation contain more information than just a specific entity with which I interact in my form. So my GET action handler will run the view model and provide each property with a given value, etc.

In my POST checker, I check if the state of the model is valid if I do not re-display the form / view with errors.

In my POST action handler, I have to copy the code from my GET action handler to redisplay the view again. How can I implement my actions with the controller so that I do not have to copy the code responsible for collecting data for the view model?

I tried to allow my handler to handle both POST and GET, but then I have input parameters that I need to deal with. My POST action handler will have a view model as an input parameter, but this will not be the case for the GET action handler.

+7
source share
5 answers

In such situations, we create collectors for our view models.

Take a look at option 3 under this post .

+4
source

Your POST handler can return an ActionResult from the GET handler, as shown below:

public ActionResult SomePageGet() { var model = new SomePageViewModel(); // Populate ViewModel: ... return View("SomePageGet", model); } [HttpPost] public ActionResult SomePagePost(SomePageViewModel input) { // Validate the model: ... if (!ModelState.IsValid) { // Return the GET page, with error messages: return SomePageGet(); } return View("Success"); } 

Since ModelState contains all error messages (and invalid input), the GET page will display them normally.

+7
source

You can simply convert the general code into an extension method of the main object that you are working on.

Then call it as many times as you want, remaining DRY .

I don’t know exactly what the function of this common code is, but basically it will be related data for a rich presentation. In this case, the solution that I prefer should allow the view to load additional data from another action using RenderAction, which can later be reorganized to refresh the AJAX page, remaining DRY and sharing the problems of the actions.

0
source

"... I need to copy the code ..."

I do not understand why; why can't you just create a member in your controller and name it? Not everything in your controller should be an action. But you might want to take a look at the builders, not the @ataddeini offer.

0
source

Your POST action method should be available only for the viewmodel type as a parameter, and not for all individual pieces of data. If the viewmodel is harder to build, you might want to write a modelbinder for your view model that can do this more complex work (your action method will still use the VM type as a parameter).

 [HttpPost] public ViewResult MyAction(MyViewModel model) { // model should now be fully populated; check ModelState.IsValid though in case there are errors (such as the user entering "abc" for an int property) } 
-one
source

All Articles