【问题标题】:Custom middleware for input validation用于输入验证的自定义中间件
【发布时间】:2018-09-13 18:15:17
【问题描述】:

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

如果满足我的验证条件,那么我不希望管道中的其他项目执行。

我需要帮助 -

  1. 如何限制管道中的其他项目执行。

  2. 如何以 JSON 的形式返回自定义错误响应。

【问题讨论】:

  • @illug 这不是我老板想做的:(
  • 买一个新的。尽快! :)
  • 不要为此使用中间件,这太低级了。请改用action filter
  • 不想使用模型状态的真正原因是什么?我可以理解它是否有时可能不够灵活(尽管通用过滤器/中间件也无法解决),但我认为这实际上只是一个没有受过教育的决定,所以你可能不应该满足于在真正考虑解决问题的正确方法之前。

标签: c# validation asp.net-core-2.0 asp.net-core-middleware


【解决方案1】:

您不应为此使用自定义中间件。中间件是非常低级的,正如您所注意到的,您必须自己阅读和解析请求正文。这不仅复杂,而且还会导致这种情况发生两次(再次在 MVC 中间件内部)。

相反,您应该使用MVC filter,尤其是action filter。过滤器作为 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)
    { }
}

【讨论】:

  • 如何根据每个字段/属性验证返回自定义响应?例如,如果我的 id 为 null,则返回“请输入 id”并且不执行其他检查。
  • 您可以在该过滤器中执行任何类型的逻辑。当然,如果您需要验证模型的实际属性(而不是使用我在这里推荐的正确模型验证),那么您将必须知道实际类型;您可以从context.ActionArguments 检索模型对象。否则,您也可以简单地将来自ModelState 的错误序列化并直接报告所有验证错误。
  • 经过长时间的讨论..我们现在准备采用ActionFilter方法..感谢@poke推理出中间件ActionFilter的用法
猜你喜欢
  • 2018-03-18
  • 2016-03-04
  • 1970-01-01
  • 2018-01-05
  • 2020-12-20
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
相关资源
最近更新 更多