如何使用动作过滤器在asp.net mvc中集中模型状态验证?

Mai*_*Ben 20 c# asp.net-mvc-4

我在几个地方编写这段代码,并且总是重复这个逻辑:

public ActionResult MyMethod(MyModel collection)
{
    if (!ModelState.IsValid)
    {
        return Json(false);//to read it from javascript, it's always equal
    }
    else
    {
        try
        {
            //logic here
            return Json(true);//or Json(false);
        }
        catch
        {
            return Json(false);//to read it from javascript, it's always equal
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法使用动作过滤器,不被重复try-catch,请问如果模型是有效的,并return Json(false)作为ActionResult

Kha*_* TO 18

要符合REST,您应该返回http错误请求400以指示请求格式错误(模型无效)而不是返回Json(false).

asp.net官方网站上试试这个属性来获取web api:

public class ValidateModelAttribute : ActionFilterAttribute
{
     public override void OnActionExecuting(HttpActionContext actionContext)
     {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

asp.net mvc的版本可能是这样的:

public class ValidateModelAttribute : ActionFilterAttribute
{
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
              if (!filterContext.Controller.ViewData.ModelState.IsValid)
              {
                   filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
              }
        }
}
Run Code Online (Sandbox Code Playgroud)


ade*_*l41 11

如果你想在MVC6或Mvc Core中执行此操作而不在所有Action方法上指定属性,那么这就是你如何做到的.

首先创建你的ActionFilter

public class ModelStateValidationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting( ActionExecutingContext context )
    {
        if ( context.HttpContext.Request.Method == "POST" && !context.ModelState.IsValid )
            context.Result = new BadRequestObjectResult( context.ModelState );
    }
}
Run Code Online (Sandbox Code Playgroud)

现在创建一个约定,在其中将ActionFilter应用于所有控制器.

    public class ModelStateValidatorConvension : IApplicationModelConvention
    {
        public void Apply( ApplicationModel application )
        {
            foreach ( var controllerModel in application.Controllers )
            {
                controllerModel.Filters.Add( new ModelStateValidationFilterAttribute() );
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

最后一件事是在MVC中注册这个约定

    public void ConfigureServices( IServiceCollection services )
    {
      services.Configure<MvcOptions>( x => x.Conventions.Add( new ModelStateValidatorConvension() ) );
    }
Run Code Online (Sandbox Code Playgroud)


Sal*_*bba 5

从 ASP.Net Core 2.1 开始,该[ApiController]属性将触发自动模型验证:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Run Code Online (Sandbox Code Playgroud)

因此,在操作方法或自定义中不需要以下代码ActionFilterAttribute

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}
Run Code Online (Sandbox Code Playgroud)

来源: https: //learn.microsoft.com/en-us/aspnet/core/web-api/ ?view=aspnetcore-2.1#automatic-http-400-responses-1