使用自定义中间件Asp.Net-Core添加响应标头

时间:2018-03-07 17:13:00

标签: c# asp.net-core

我有3个微服务并尝试创建相关ID以跟踪每个日志问题。如果请求到来时corrID不为null,那么我设置它。如果不是,则生成它。然后传递到下一个。我想看看3个服务的问题'日志。如果我使用下面的代码一切正常。但招摇不起作用。

异常:标头是只读响应已经开始。

 public async Task Invoke(HttpContext context)
            {
                string key = context.Request.Headers.Keys.FirstOrDefault(n => n.Equals("Correlation-ID"));

                var corrID = context.RequestServices.GetService<CorrelationID_Global>();

                if (corrID != null)
                {
                    if (!string.IsNullOrWhiteSpace(key))
                    {

                        corrID.ID = context.Request.Headers[key].ToString();
                    }
                    else
                    {
                        corrID.ID = Guid.NewGuid().ToString();

                    }
                }

                await _next(context);

                if (!string.IsNullOrWhiteSpace(corrID?.ID))
                {               
                        context.Response.Headers.Add("Correlation-ID", corrID.ID);
                }

            }

要解决招摇问题,我使用以下链接更改最后一条if语句:Add Response Headers to ASP.NET Core Middleware

  if (!string.IsNullOrWhiteSpace(corrID?.ID))
    {
        context.Response.OnStarting((state) =>
        {
            context.Response.Headers.Add("Correlation-ID", corrID.ID);
            return Task.FromResult(0);
        },null);
    }

然而,这次我无法在回复中看到相关性ID。服务日志。这是对请求的重要性。日志像往常一样变化。我该如何处理这个问题?谢谢。

1 个答案:

答案 0 :(得分:2)

正确的方法是在REQ/REP之前注册context.Response.OnStarting回调,因为管道中的下一个中间件之一将启动响应。

换句话说,使用当前的实现,您的await _next(context);回调不会因为注册太晚而被触发。将中间件代码更改为

OnStarting