添加委托处理程序时,HttpContext.Current为null

时间:2019-03-24 07:25:42

标签: asp.net asp.net-web-api nlog httphandler

在我的一个项目中,我添加了委托处理程序来记录传入和传出的请求。对于日志记录,我使用的是Nlog。我正在为每个请求生成一个唯一ID,以将日志与此特定ID相关联。 这对我来说很好。现在,最近我在处理程序中修改了我的代码,并将HttpContext.Currnet.Item值设置为此唯一的ID。现在,我应该获取此ID,并将其传递给外部Apis。

我遇到的问题在控制器HttpContext内部.Current为null。 我知道主要的根本原因是什么。这是因为handler.SendAsync导致线程SynchronizationContext为空。

我想将HttpContext.Current传递给正在进行的线程。

我做了什么:

我设置了ConfigureAwait(false) 我将appsettings-> aspnet:UseTraskFriendlySynchronizationContext设置为true

但是这些不起作用。

我正在使用.net Framework 4.7.1

1 个答案:

答案 0 :(得分:0)

感谢@Alexander, 在您发表评论之后,我再次查看了我的代码,发现此问题不是由await base.SendAsync()引起的。事实上,我正在使用async调用内部方法,从而破坏了HttpContext.Current。

下面是我的DelegatingHandler实现,以供参考。在此之前,我定义了两种方法,即IncommingMessageAsync()和OutgoingMessageAsync作为Async。现在,我已将其更改为简单方法。因为我不希望在这些方法中使用Task。

 public  class MessageHandler : DelegatingHandler
{
    private static NLog.Logger logger;
    HttpContext context;

    public MessageHandler()
    {
        logger = NLog.LogManager.GetCurrentClassLogger();
    }
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var correlationID = $"{DateTime.Now.Ticks}{Thread.CurrentThread.ManagedThreadId}";
        context = HttpContext.Current;
        context.Items["correlationID"] = correlationID;     //used in Nlog aspnet-item:variable=correlationID
        IncommingMessageAsync(request);
        var response = await base.SendAsync(request, cancellationToken);
        context.Items["responseTime"] = DateTime.Now;
        HttpContext.Current = context;
        OutgoingMessageAsync(response);
        return response;
    }
    protected void IncommingMessageAsync(HttpRequestMessage request)
    {
        logger.Info("Request Received from {URL}", request.Method + " " + request.RequestUri);
    }
    protected void OutgoingMessageAsync(HttpResponseMessage response)
    {
        if (response.IsSuccessStatusCode)
        {
            logger.Info("Resposne Returned with Status {Status}", response.StatusCode);
        }
        else
        {
            logger.Warn("Resposne Returned with Status {Status}", response.StatusCode);
        }
    }
}