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

时间:2014-02-09 02:57:34

标签: 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
        }
    }
}

有没有办法使用操作过滤器,而不是重复try-catch,询问模型是否有效且return Json(false)ActionResult

4 个答案:

答案 0 :(得分:16)

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

尝试使用asp.net official site中的此属性来获取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);
        }
    }
}

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

答案 1 :(得分: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 );
    }
}

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

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

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

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

答案 2 :(得分:1)

以下是如何使用Khanh TO(来自asp.net official site)的代码:

要将此过滤器应用于所有Web API控制器,请在配置期间将过滤器的实例添加到HttpConfiguration.Filters集合中:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Filters.Add(new ValidateModelAttribute());

        // ...
    }
}

另一种选择是将过滤器设置为各个控制器或控制器操作的属性:

public class ProductsController : ApiController
{
  [ValidateModel]
  public HttpResponseMessage Post(Product product)
  {
    // ...
  }
}

答案 3 :(得分:0)

public class ValidateModelStateAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {              
            context.Result = new ViewResult();
        }
    }
}