【问题标题】:HttpContext.Current is null when adding delegate handler添加委托处理程序时 HttpContext.Current 为 null
【发布时间】:2019-03-24 07:25:42
【问题描述】:

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

我面临的问题是在控制器内部 HttpContext.Current 为空。 我知道主要的根本原因是什么。这是因为handler.SendAsync,会使线程SynchronizationContext为null。

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

我做了什么:

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

但这些都不起作用。

我正在使用 .net 框架 4.7.1

【问题讨论】:

  • 这就是你要找的东西(?):stackoverflow.com/questions/14181408/…
  • 对我来说很好。您能否提供您的处理程序和控制器的相关代码?
  • 谢谢@Alexander 我得到了解决方案。请查看我提出的答案

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


【解决方案1】:

感谢@Alexander, 在您的 cmets 之后,我再次查看了我的代码,发现这个问题不是由 await base.SendAsync() 引起的,实际上我是在使用异步调用内部方法,这破坏了 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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-14
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多