簡體   English   中英

ASP.NET 異常時Core HttpContext.Response.StatusCode為200

[英]ASP.NET Core HttpContext.Response.StatusCode is 200 when exception

我有一個拋出異常的端點。

[ApiController]
[Route("api")]
public class LegacyController : ControllerBase
{
    [HttpPost("endpoint")]
    public async Task<ActionResult<IEnumerable<Entitty>>> GetAll()
    {
        throw new Exception();
        return Ok(t.ToList());
    }
}

我有自定義 Http 日志過濾器,看起來像這樣

using Microsoft.AspNetCore.Http;

namespace Client.API.Extensions
{
    public class HttpLoggingMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public HttpLoggingMiddleware(RequestDelegate next, ILogger<HttpLoggingMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            finally
            {
                _logger.LogInformation(
                    "Request {method} {url} => {statusCode}",
                    context.Request?.Method,
                    context.Request?.Path.Value,
                    context.Response?.StatusCode);
            }
        }
    }
}

當我調用此端點時,context.Response?.StatusCode 為 200。為什么?

然而,Postman 告訴我我的請求失敗了,我看到了錯誤本身,因此一切看起來都很正常。 盡管日志包含 200 條狀態代碼消息,而不是 500。

編輯:這是我的啟動(一些部分被刪除)。

namespace Client.API
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...
            app.UseHttpsRedirection();

            app.UsePathBase(new PathString(basePath));
            app.UseRouting();

            app.UseMiddleware<HttpLoggingMiddleware>();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
            endpoints.MapControllers();
            });
        }
    }
}

如果你想捕獲異常,你需要使用特定的中間件app.UseExceptionHandler(); ,所以首先我使用這個中間件來設置日志。

代碼是:

app.UseExceptionHandler(
  appErr =>
  {
    appErr.Run(
    async context =>
    {
      logger.LogInformation(
      "Request {method} {url} => {statusCode}",
       context.Request?.Method,
       context.Request?.Path.Value,
       context.Response?.StatusCode);
    });
});

但是有一個問題,這個中間件只能捕獲異常,所以當響應碼不是500時,請求不會進入這個中間件。

最后我換了一個方法,我用try/catch來捕獲異常,自己設置StatusCode就成功了。 代碼如下:

public class HttpLoggingMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<HttpLoggingMiddleware> _logger;

        public HttpLoggingMiddleware(RequestDelegate next,ILogger<HttpLoggingMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception)
            {
                //catch the Exception and set the StatusCode 
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            }
            finally
            {
                _logger.LogInformation(
                    "Request {method} {url} => {statusCode}",
                    context.Request?.Method,
                    context.Request?.Path.Value,
                    context.Response?.StatusCode);
            }
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM