c# - 在中间件asp.net core 2中设置捕获错误的主体

标签 c# exception asp.net-core-2.0 asp.net-core-webapi

我已点击以下链接;

Custom HttpResponseException Middleware Asp.Net Core 2.0

我现在想向响应正文添加一条消息,以提供异常的上下文。

我修改了中间件Invoke方法如下;

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (HttpStatusCodeException exception)
        {
            context.Response.StatusCode = (int)exception.StatusCode;
            // byte[] data = Encoding.UTF8.GetBytes(exception.Message);
            // await context.Response.Body.WriteAsync(data, 0, data.Length);
            await context.Response.WriteAsync(exception.Message);
            context.Response.Headers.Clear();
        }
    }

但是,当将 WriteAsync 行添加到方法中时,我没有收到 Api 的响应(我正在通过 postman 进行测试)。

任何人都可以指出我在这里做错了什么的正确方向吗?

类和中间件的完整代码如下;

namespace Services.WebApi.Middleware
{
    public class HttpErrorHandlerMiddleware
    {

        private readonly RequestDelegate _next;

        public HttpErrorHandlerMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (HttpStatusCodeException exception)
            {
                context.Response.StatusCode = (int)exception.StatusCode;
                // byte[] data = Encoding.UTF8.GetBytes(exception.Message);
                // await context.Response.Body.WriteAsync(data, 0, data.Length);
                await context.Response.WriteAsync(exception.Message);
                context.Response.Headers.Clear();
            }
        }
    }

    public static class HttpErrorHandlerMiddlewareExtensions
    {
        public static IApplicationBuilder UseHttpErrorHandlerMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<HttpErrorHandlerMiddleware>();
        }
    }
}

HttpStatusCodeException类如下;

    public class HttpStatusCodeException : Exception
{
    public HttpStatusCode StatusCode { get; set; }

    public HttpStatusCodeException(HttpStatusCode statusCode)
    {
        StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, string message) : base(message)
    {
        StatusCode = statusCode;
    }

}

最佳答案

这个

await context.Response.WriteAsync(exception.Message);
context.Response.Headers.Clear();

不起作用,因为在发送响应之后(通过 Response.WriteAsync) - header 无法更改\清除,因为 header 是在响应正文之前发送的,所以此时已经发送给客户。只需更改顺序即可:

context.Response.Headers.Clear();
await context.Response.WriteAsync(exception.Message);

它应该按预期工作。还值得检查此时响应尚未开始:

if (!context.Response.HasStarted) {
    context.Response.Headers.Clear();
    await context.Response.WriteAsync(exception.Message);
}

还要确保您的中间件在其他中间件之前注册。右:

app.UseHttpErrorHandlerMiddleware();
app.UseMvc();

错误

app.UseMvc();
app.UseHttpErrorHandlerMiddleware();

关于c# - 在中间件asp.net core 2中设置捕获错误的主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49293562/

相关文章:

c# - 添加元素时 xmlns 属性创建为空

c# - HttpWeb 请求错误 : 503 server unavailable

java - 处理异常

vba - VBA-如何检查字符串是否为有效的十六进制颜色代码?

angular-cli - Angular CLI 6 - ng build 不生成服务器包

c# - 无法立即在 Npgsql 中收到多个通知

c# - 在 C# 中将数据对象导入/导出到 CSV

C++ 异常 std::length_error 有时?

c# - 带有 id 的 asp.net core 2 razor 页面路由

asp.net-core - .net core 2 中 fuslogvw 的替代品是什么?