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

ぃ、小莉子 提交于 2021-01-27 07:41:00

问题


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);
}

回答1:


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




回答2:


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.




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/24159615/model-validation-in-web-api-exception-is-thrown-with-out-a-throw-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!