Model validation in Web API - Exception is thrown with out a throw statement?

I have seen the model validation from here (Under section: Handling Validation Errors).

The code-snippet is as below in Web API

public class ValidateModel : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, actionContext.ModelState);
            }

            base.OnActionExecuting(actionContext);
        }
    }

The problem is upon validation of model, if there were any errors, it assigns an model state invalid exception.

And after that, before going to the actual method (which is decorated with this [ValidateModel] attribute), WebAPI simply returns a 400 request.

But how ? Which function is returning a HTTP 400?

What happens after this method is done executing? Where does the control flow ?

EDIT:

The action that I am applying this attribute to is a normal one.

[ValidateModel]
public IHttpActionResult Post([FromBody]Request)
{
//do normal business logics here.
return Ok(SuccessMessage);
}

Upvotes: 6

Views: 10601

Answers (5)

Carlos
Carlos

Reputation: 706

In VBA.NET API REST Validate model

Imports System.ComponentModel.DataAnnotations

Public Class Client
    <Required(ErrorMessage:="Dpi is required")>
    Public Property Dpi As String

    <MaxLength(16, ErrorMessage:="El NAME no debe ser mayor a 16 caracteres.")>
    Public Property NAME As String
End Class

CONTROLLER

    <Route("UPDATE/client")>
    <ActionName("description to do...")>
    <HttpPost>
    Public Function saveClient(ByVal cli As Client)


        If ModelState.IsValid Then
            return Request.CreateResponse(HttpStatusCode.OK, True)
        Else
            Return BadRequest(ModelState)
        End If
 End Function

Upvotes: 0

brainless coder
brainless coder

Reputation: 6430

To understand the control flow you first need to visit this link here -

Action Attribute Class Reference

Check the method sections there. If clearly states that, OnActionExecuting is performed before that particular action, decorated with this attribute, is executed and OnActionExecuted is performed after the execution is complete. Since you are implementing OnActionExecuting like this -

public class ValidateModel : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }

        base.OnActionExecuting(actionContext);
    }
}

and since the error is thrown inside this method, like this -

 if (actionContext.ModelState.IsValid == false)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }

Your method will only execute if the OnActionExecuting method finds a valid model. And from the error 400, it seems that your current model state is not valid and thus it fails to succeed and your method will never be executed unless you provide a valid model. Set a debug point inside this method and you can find out why it fails.

By the way, the exception is not thrown its just a standard response that is handled by -

base.OnActionExecuting(actionContext);

http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute(v=vs.118).aspx

Upvotes: 7

Tibi
Tibi

Reputation: 1547

If your Request data type is defined as struct, or an abstract class, it cannot be instantiated, and that might be the probable cause. If is a struct, just make it Nullable, if it is an abstract class or interface you can either create your own ModelBinder to deal with the creation, or you can change it with a concrete implementation.

Upvotes: 1

J. Davidson
J. Davidson

Reputation: 3307

When method OnActionExecuting is called it checks to see if the Model is valid. If Model is not valid actionContext.Response will be calling server which will return 400 code back meaning the it was bad request. It all depends how you are calling this web api. Normally you can have jquery or some other libraries or code behind from asp.net making the call to the webapi's with appropriate object. That object is first checked if it is valid or not. If it is valid it will keep processing nothing is returned back. If object state is invalid than it will return the status code 400. If it is returning 200 than it means your object is valid and web api executed and is returning 200. This 200 is not being returned from webapi but from EF after data was written sucessfully. If you want to use try catch block than you dont need to check if model is valid. Just pass through the url with object and wait for response than catch it and display.

Upvotes: 1

ashish
ashish

Reputation: 245

To find the error point just create a break point on Application_Error in Global.asax and follow the error details and stack trace to find the origin for the same.

Upvotes: 1

Related Questions