问题描述
我有一个自定义的 IModelBinder
我的模型:
I have a custom IModelBinder
for my model:
public class MyBinder : IModelBinder {
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) {
// bla-bla-bla
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Request value is invalid.");
return false;
}
}
我希望,当无效值传递的请求的HTTP 400错误的请求自动返回。但是,这并没有发生。我应该怎么做才能让网页API返回的HTTP 400,如果有任何约束力的错误?
I expect that when invalid value is passed in a request HTTP 400 Bad Request is returned automatically. However, this does not happen. What should I do to make Web API return HTTP 400 if there are any binding errors?
推荐答案
您可以做漂亮的codeR建议但还有很多不足之处,因为你需要重复的每一个动作。我建议你创建一个ActionFilterAttribute这onActionExecuting和onActionExecuted验证该ModelState中是有效的,并返回BadRequest。然后,您可以将此单独行动为 [BadRequestIfModelNotValid]
或全局过滤器,把它应用到每一个请求。
You can do as beautifulcoder suggests but that leaves much to be desired because you need to repeat that on every action. I would suggest your create an ActionFilterAttribute which onActionExecuting and onActionExecuted validates that the modelstate is valid and returns the BadRequest. You can then apply this to separate actions as [BadRequestIfModelNotValid]
or to the global filters to have it applied to every requests.
public sealed class BadRequestIfModelNotValidAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
/// <summary>
/// if the modelstate is not valid before invoking the action return badrequest
/// </summary>
/// <param name="actionContext"></param>
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var modelState = actionContext.ModelState;
if (!modelState.IsValid)
actionContext.Response = generateModelStateBadRequestResponse(modelState, actionContext.Request);
base.OnActionExecuting(actionContext);//let other filters run if required
}
/// <summary>
/// if the action has done additional modelstate checks which made it invalid we are going to replace the response with a badrequest
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var modelState = actionExecutedContext.ActionContext.ModelState;
if (!modelState.IsValid)
actionExecutedContext.Response = generateModelStateBadRequestResponse(modelState, actionExecutedContext.Request);
base.OnActionExecuted(actionExecutedContext);
}
private HttpResponseMessage generateModelStateBadRequestResponse(IEnumerable<KeyValuePair<string, ModelState>> modelState, HttpRequestMessage request)
{
var errors = modelState
.Where(s => s.Value.Errors.Count > 0)
.Select(s => new ApiErrorMessage {
Parameter = s.Key,
Message = getErrorMessage(s.Value.Errors.First())
}) //custom class to normalize error responses from api
.ToList();
return request.CreateResponse(System.Net.HttpStatusCode.BadRequest, new ApiError
{
ExceptionType = typeof(ArgumentException).FullName,
Messages = errors
});
}
/// <summary>
/// retrieve the error message or fallback to exception if possible
/// </summary>
/// <param name="modelError"></param>
/// <returns></returns>
private static string getErrorMessage(ModelError modelError)
{
if(!string.IsNullOrWhiteSpace(modelError.ErrorMessage))
return modelError.ErrorMessage;
if(modelError.Exception != null)
return modelError.Exception.Message;
return "unspecified error";
}
}
这篇关于在ASP.NET的Web API模型绑定验证参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!