arp*_*tro 2 c# validation asp.net-core-middleware asp.net-core-2.0
我的API只有POST操作方法。我想创建一个库来验证对我的API的输入。现在,我想在点击控制器操作方法之前进行此验证。
我决定使用中间件方法-
public class ValidateInputMiddleware
{
private readonly RequestDelegate _next;
public ValidateInputMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
//read the request body
//serialize the json body to input model
//validations
if(reqJsonObj.Id == null)
//return response - id is null
//other validations
await _next(httpContext);
}
}
Run Code Online (Sandbox Code Playgroud)
如果满足我的验证条件,那么我不希望管道中的其他项目执行。
我需要帮助-
我如何限制执行中的其他项目。
如何以JSON形式返回自定义的错误响应。
您不应为此使用自定义中间件。中间件是非常底层的,正如您所注意到的,您将必须自己阅读和解析请求主体。这不仅很复杂,而且还会导致这种情况发生两次(同样在MVC中间件内部)。
相反,您应该使用MVC过滤器,尤其是动作过滤器。筛选器作为MVC管道的一部分运行,因此您可以依赖MVC管道已经为您完成的各种操作,例如模型绑定或授权。
这也使终止响应并返回自定义JSON响应变得更加容易,因为您不必再次手动序列化内容,而是可以使用高级MVC结果。
针对您的情况的操作过滤器可能如下所示:
public class InputValidationActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// we can even *still* use model state properly…
if (!context.ModelState.IsValid)
{
var responseObj = new {
successful = false,
error = "The input is not valid",
};
// setting the result shortcuts the pipeline, so the action is never executed
context.Result = new JsonResult(responseObj)
{
StatusCode = 400
};
}
}
public void OnActionExecuted(ActionExecutedContext context)
{ }
}
Run Code Online (Sandbox Code Playgroud)