views:

21

answers:

1

I'm implementing a web API using the REST for ASP.NET MVC framework (MVC 2). I want to encapsulate this code, ideally in an ActionFilterAttribute (?), so that I can decorate specific actions that always perform this same logic:

if (!ModelState.IsValid) {
  return View(
    new GenericResultModel(){ HasError=True, ErrorMessage="Model is invalid."});
}

I really don't want to have to copy and paste this boilerplate code into every controller action where I need to do this.

In this web API scenario, I need to be able to do something like this so that the caller can get a result back in JSON or POX form and see that there is an error. In an ASPX view, obviously I wouldn't need something like this as the validation controls would take care of notifying the user of a problem. But I do not have an ASPX view - I am only returning JSON or POX data serialized from my model.

I've started with this code in an ActionFilter but am not sure what to do next (or if it is even the right starting point):

public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        bool result = filterContext.Controller.ViewData.ModelState.IsValid;
        if (!result)
        {
            GenericResultModel m = new GenericResultModel() { HasError = true };
            // return View(m)
            // ?????
        }

        base.OnActionExecuting(filterContext);
    }     

How do I accomplish this?

+2  A: 
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    // Notice that the controller action hasn't been called yet, so
    // don't expect ModelState.IsValid=false here if you have 
    // ModelState.AddModelError inside your controller action
    // (you shouldn't be doing validation in your controller action anyway)
    bool result = filterContext.Controller.ViewData.ModelState.IsValid;
    if (!result)
    {
        // the model that resulted from model binding is not valid 
        // => prepare a ViewResult using the model to return
        var result = new ViewResult();
        result.ViewData.Model = new GenericResultModel() { HasError = true };
        filterContext.Result = result;
    }
    else
    {
        // call the action method only if the model is valid after binding
        base.OnActionExecuting(filterContext);
    }
}
Darin Dimitrov
this approach is working great. thanks!
Mike Hodnick