在我的ASP.NET核心控制器中,我总是检查ModelState是否有效:
[HttpPost("[action]")]
public async Task<IActionResult> DoStuff([FromBody]DoStuffRequest request)
{
if (!ModelState.IsValid)
{
return BadRequest("invalid parameters");
}
else
{
return Ok("some data"));
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法使用过滤器全局检查ModelState的有效性,所以我不必再次在每个控制器的每个API项目中执行此操作?如果动作可以依赖于模型状态是有效的而不需要检查,那将是很好的:
[HttpPost("[action]")]
public async Task<IActionResult> DoStuff([FromBody]DoStuffRequest request)
{
return Ok("some data"));
}
Run Code Online (Sandbox Code Playgroud)
你可以使用ActionFilter
.它不是全局的,但它将问题从您的方法体转移到属性中.我意识到它并没有完全解决你的问题,但它可能比什么都没有好.
public class ModelStateValidationActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var modelState = actionContext.ModelState;
if (!modelState.IsValid)
actionContext.Response = actionContext.Request
.CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
}
}
Run Code Online (Sandbox Code Playgroud)
在你的控制器中:
[HttpPost]
[ModelStateValidationActionFilter]
public IHttpActionResult Post(object model)
{
}
Run Code Online (Sandbox Code Playgroud)
我相信你也可以在你的控制器上设置它.我实际上没有尝试过,但据此,它可以工作.
[ModelStateValidationActionFilter]
public class MyApiController : ApiController
{
}
Run Code Online (Sandbox Code Playgroud)
编辑:
正如@Camilo Terevinto所说,Core有点不同.ActionFilter
如果你想使用Core,只需使用它.
public class ModelStateValidationActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var modelState = context.ModelState;
if (!modelState.IsValid)
context.Result = new ContentResult()
{
Content = "Modelstate not valid",
StatusCode = 400
};
base.OnActionExecuting(context);
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,现有的答案是ASP.NET Web API而不是ASP.NET Core.在ASP.NET Core中实际执行此操作的方法是:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
}
public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
Run Code Online (Sandbox Code Playgroud)
并且您可以在Startup.cs中全局注册此过滤器,因此这将在每次调用中执行,您不必在每个操作/控制器中重复它:
options.Filters.Add(typeof(SampleActionFilter));
Run Code Online (Sandbox Code Playgroud)
后续操作:在ASP.NET Core 2.1中,有一个名为的控制器属性[ApiController]
。如果包含该属性,它将自动使用一个ActionFilter
名为的内置ModelStateInvalidFilter
函数,这意味着将永远无法访问检查ModelState的任何自定义操作过滤器,因为该[ApiController]
属性已经注册了自己的过滤器。
为了抑制此行为,当前文档提供了以下选项:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true; // This is the setting
});
Run Code Online (Sandbox Code Playgroud)
对于 ASP.NET Core 2.0,避免对所有Controllers
或Actions
单独应用属性;
定义过滤器:
namespace Test
{
public sealed class ModelStateCheckFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context) { }
public void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的 中Startup.cs
,将其添加为过滤器:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(config =>
{
config.Filters.Add(new ModelStateCheckFilter());
});
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5353 次 |
最近记录: |