16

I have a pre-action web api hook that will check ModelState.IsValid. If the ModelState is not valid I do not want to execute the action and just return my message immediately. How exactly do I do this?

public class ValidateModelStateAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) {
        if (!actionContext.ModelState.IsValid)
        {
            var msg = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            // Now What?
        }
        base.OnActionExecuting(actionContext);
    }
}
George Mauer
  • 117,483
  • 131
  • 382
  • 612

3 Answers3

36

set the Response.Result. If the result is not null it will not execute the action. the exact syntax is escaping me right now, but it's as simple as

if(actionContext.ModelState.IsValid == false)
{
       var response = actionContext.Request.CreateErrorResponse(...);
       actionContext.Response = response;
}   
Jason Meckley
  • 7,589
  • 1
  • 24
  • 45
  • I see, do I then call the base or not? What I really would like is for all pre-action filters to run but not the action itself. That way any logging filters would still run – George Mauer May 29 '13 at 19:42
  • incidentally.. just curious what is the purpose of calling the base.. when should we call the base.. and when not ? – joedotnot Jan 23 '19 at 06:55
7

Have you actually seen the example on the ASP.NET WebApi page?

Looks very much like what you're trying to achieve and all they do is setting the Response of the Context object:

If model validation fails, this filter returns an HTTP response that contains the validation errors. In that case, the controller action is not invoked.

http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api

see: Handling Validation Errors

Joanna Derks
  • 4,033
  • 3
  • 26
  • 32
2

My guess is that you should throw a HttpResponseException

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • You think that would work the same as just returning the message? Not in a compiling state so I can't check atm but it seems strange to throw exceptions for validation issues. – George Mauer May 29 '13 at 19:37
  • @GeorgeMauer It will work for ActionFilters, not sure about AuthorizationFilters. As Joanna mentioned apparently you can also just set the Response. Wow, I really hate ActionFilters, so much complexity for no reason. – Darrel Miller May 29 '13 at 20:28
  • What do you mean? How else do you do cross-cutting concerns? Using base classes for this generally turns into a huge inflexible mess once you get enough cross-cutting concerns. The only other option ends up being something like PostSharp which has its own host of issues. – George Mauer May 30 '13 at 16:58
  • @GeorgeMauer I use MessageHandlers for most of my cross cutting concerns. For action specific stuff, what is really the difference between adding an Authorize attribute and calling Authorize() in the action itself? At least with a direct call I know exactly when it is going to happen. – Darrel Miller May 30 '13 at 18:54
  • I need to look into MessageHandlers - as for the other one - the difference is that filters can be added globally and be part of your infrastructure. – George Mauer May 30 '13 at 20:32
  • @GeorgeMauer Anything I want to do globally I do with MessageHandlers. – Darrel Miller May 30 '13 at 21:14