【问题标题】:asp.net core middleware can't catch newtonsoft exceptionasp.net 核心中间件无法捕获 newtonsoft 异常
【发布时间】:2019-06-06 00:40:46
【问题描述】:

我使用中间件捕获请求异常并像这样写响应

public async Task Invoke(HttpContext context /* other dependencies */)
{
    try
    {

        await next(context);
    }
    catch (Exception ex)
    {
        logger.LogError(ex.Message);
        await HandleExceptionAsync(context, ex); //write response
    }
}
    private static Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        FanjiaApiResultMessage resultMessage = new FanjiaApiResultMessage()
        {
            ResultCode = -1,
            Data = null,
            Msg = exception.Message
        };
        string result = JsonConvert.SerializeObject(resultMessage);
        context.Response.ContentType = "application/json;charset=utf-8";
        if (exception is QunarException)
        {
            context.Response.StatusCode = (int)(exception as QunarException).httpStatusCode;
        }
        else
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        return context.Response.WriteAsync(result);
    }

这样的请求模型参数

public class FlightModel {
   [JsonProperty("depCity", Required = Required.Always)]
   public string DepCity { get; set; }
}

public IActionResult Test(FlightModel model){
  return Content("test");
}

当我发布没有 DepCity 的 FlightModel 时,我会得到异常

{
    "errors": {
        "": [
            "Required property 'depCity' not found in JSON. Path '', line 6, position 1."
        ]
    },
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "8000000a-0003-ff00-b63f-84710c7967bb"
}

显然异常没有被中间件捕获。

为什么中间件没有被捕获?

【问题讨论】:

  • 你能告诉我们你的Configuration.cs吗?我有一种感觉,您可能没有正确订购它以使您的中间件首先在请求管道上命中。
  • @Svek 感谢您的回复。我把它放在 app.UseMvc(); 前面我认为 Simon C 是对的,这很有用

标签: c# asp.net-core json.net


【解决方案1】:

Aspnet Core 模型验证失败不会引发异常。它以默认格式提供自己的响应,状态代码为 400(错误请求)。

有几种方法可以覆盖它,包括自定义属性:https://www.jerriepelser.com/blog/validation-response-aspnet-core-webapi/

看起来像这样:

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

然后像这样添加:

[Route("api/values")]
[ValidateModel]
public class ValuesController : Controller
{
...
}

或者您可以通过覆盖 InvalidModelStateResponseFactory 来控制响应生成,就像在这个 SO 问题中一样:How do I customize ASP.Net Core model binding errors?

这是一个例子:

services.Configure<ApiBehaviorOptions>(o =>
{
    o.InvalidModelStateResponseFactory = actionContext =>
        new MyCustomBadRequestObjectResult(actionContext.ModelState);
});

【讨论】:

    猜你喜欢
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 2013-01-26
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多