在asp.net核心中间件上获取异常的空响应 [英] Getting empty response on asp.net core middleware on exception

查看:107
本文介绍了在asp.net核心中间件上获取异常的空响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个中间件,该中间件可以记录响应正文以及全局管理异常,因此我成功了.我的问题是,我放入例外的自定义消息没有显示在响应中.

I am trying to create a middleware that can log the response body as well as manage exception globally and I was succeeded about that. My problem is that the custom message that I put on exception it's not showing on the response.

中间件代码01:

public async Task Invoke(HttpContext context)
{
    context.Request.EnableRewind();

    var originalBodyStream = context.Response.Body;
    using (var responseBody = new MemoryStream())
    {
        try
        {
            context.Response.Body = responseBody;
            await next(context);

            context.Response.Body.Seek(0, SeekOrigin.Begin);
            var response = await new StreamReader(context.Response.Body).ReadToEndAsync();
            context.Response.Body.Seek(0, SeekOrigin.Begin);

            // Process log
             var log = new LogMetadata();
             log.RequestMethod = context.Request.Method;
             log.RequestUri = context.Request.Path.ToString();
             log.ResponseStatusCode = context.Response.StatusCode;
             log.ResponseTimestamp = DateTime.Now;
             log.ResponseContentType = context.Response.ContentType;
             log.ResponseContent = response;
             // Keep Log to text file
             CustomLogger.WriteLog(log);

            await responseBody.CopyToAsync(originalBodyStream);
        }
        catch (Exception ex)
        {
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            var jsonObject = JsonConvert.SerializeObject(My Custom Model);
            await context.Response.WriteAsync(jsonObject, Encoding.UTF8);
            return;
        }
    }
}

如果我这样编写中间件,则我的自定义异常可以正常工作,但无法记录响应正文.

If I write my middleware like that, my custom exception is working fine but I unable to log my response body.

中间件代码02:

 public async Task Invoke(HttpContext context)
  {
    context.Request.EnableRewind();

    try
    {
        await next(context);
    }
    catch (Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        var jsonObject = JsonConvert.SerializeObject(My Custom Model);
        await context.Response.WriteAsync(jsonObject, Encoding.UTF8);
        return;
    }
}

我的控制器操作:

    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        throw new Exception("Exception Message");
    }

现在,我想在中间件01上显示异常消息,但是它不起作用,但可以在中间件02上工作.

Now i want to show my exception message with my middleware 01, but it does't work but its work on my middleware 02.

所以我的观察是读取上下文响应时出现了问题.我的中间件01代码中缺少什么吗?

So my observation is the problem is occurring for reading the context response. Is there anything I have missed in my middleware 01 code?

是否有更好的方法来实现我的目的,即记录响应正文以及全局管理异常?

Is there any better way to serve my purpose that log the response body as well as manage exception globally?

推荐答案

我认为您在说的是此代码未将其响应发送给客户端.

I think what you are saying is that this code isn't sending it's response to the client.

 catch (Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        var jsonObject = JsonConvert.SerializeObject(My Custom Model);
        await context.Response.WriteAsync(jsonObject, Encoding.UTF8);
        return;
    }

这样做的原因是await context.Response.WriteAsync(jsonObject, Encoding.UTF8);并未写入原始主体流,而是写入了可寻找的内存流.因此,在写入后,您必须将其复制到原始流.因此,我认为代码应如下所示:

The reason for this is that await context.Response.WriteAsync(jsonObject, Encoding.UTF8); isn't writing to the original body stream it's writing to the memory stream that is seekable. So after you write to it you have to copy it to the original stream. So I believe the code should look like this:

 catch (Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        var jsonObject = JsonConvert.SerializeObject(My Custom Model);
        await context.Response.WriteAsync(jsonObject, Encoding.UTF8);

        context.Response.Body.Seek(0, SeekOrigin.Begin);    //IMPORTANT!
        await responseBody.CopyToAsync(originalBodyStream); //IMPORTANT!
        return;
    }

这篇关于在asp.net核心中间件上获取异常的空响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆