在中间件asp.net core 2

时间:2018-03-15 07:18:27

标签: c# exception-handling 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获得响应(我正在通过邮递员进行测试)。

有人能指出我正确的方向,我在这里做错了吗?

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

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;
    }

}

1 个答案:

答案 0 :(得分:1)

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

不会起作用,因为在你发送了respose(通过Response.WriteAsync)之后 - 标题无法更改\清除,因为标题是在响应正文之前发送的,所以此时已经发送给客户端。只需改变这样的顺序:

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();