Question

I want to create a custom modelbinder which validates the bounded model. I have found several examples of this and it works as it should. But I want to also to be able to send the user back to the page he came from if there is errors in the model.

Is this possible to do and are there any obvious side effects by doing this?

What I want to achieve is that the controller always gets valid commands, so I do not need to check for model.IsValid() in the action method.

Was it helpful?

Solution

What you try to do looks good, but it won't work. There're too many restrictions.

  1. Usually, only controller can decide where to redirect in case of an error. You can use additional attributes like [OnError("Action")] but this looks like workarounds.
  2. Form doesn't post all data. For example, dropdown lists, auxiliary values have to be filled by controller. You can probably use action filters for this but this is once again looks like a hack.

You can setup global action filter (on base controller) that will check for model errors (that binder sets) and redirect (setup .Result). But this is convoluted and requires too much extra "code" - attributes, etc., that is then hard to track and relate to real application logic. And it becomes too restrictive soon (see law of leaky abstraction), when you need not just simple action name on error redirect, etc.

This looks much simpler when done like this:

public ActionResult PostAction(ViewModel data)
{
   if (!ModelState.IsValid)
      return View("GetAction", data.WithDropDownList(repository.GetProducts()));

}

In the above example, controller has the control over the workflow, just as it should be. It also has freedom to perform additional verification/setup. You can still use as much infrastructure as possible - model binders to provide ModelState errors, etc - but only controller should have the final decision on the input and output.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top