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

mfuanj7w  于 2023-03-05  发布在  .NET
关注(0)|答案(1)|浏览(140)

在我的一个项目中,我添加了委托处理程序来记录传入和传出的请求。对于日志记录,我使用Nlog。我生成了一个唯一的ID,每个请求都将日志与此特定ID相关联。这对我来说很好。最近我修改了处理程序中的代码,并将HttpContext.Currnet.Item值设置为此唯一ID。现在我应该获得此ID,并将其传递给外部API。
我遇到的问题是在控制器HttpContext内部。当前为空。我知道主要的根本原因是什么。这是因为处理程序. SendAsync会使线程SynchronizationContext为空。
我想把HttpContext.current传递给正在进行的线程。
我做了什么:
我设置了配置等待(false)我设置了应用程序设置-〉aspnet:UseTraskFriendlySynchronizationContext为true
但这些都不管用。
我使用的是. net框架4.7.1

abithluo

abithluo1#

谢谢@ Alexandria ,
在你的评论之后,我再次检查了我的代码,发现这个问题不是由await base.SendAsync()引起的。事实上,我是用异步调用内部方法,这破坏了HttpContext.Current
下面是我的DelegatingHandler实现,作为参考。在此之前,我定义了两个方法,即IncomingMessageAsync()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
        IncomingMessageAsync(request);
        var response = await base.SendAsync(request, cancellationToken);
        context.Items["responseTime"] = DateTime.Now;
        HttpContext.Current = context;
        OutgoingMessageAsync(response);
        return response;
    }

    protected void IncomingMessageAsync(HttpRequestMessage request)
    {
        logger.Info("Request received from {URL}", request.Method + " " + request.RequestUri);
    }

    protected void OutgoingMessageAsync(HttpResponseMessage response)
    {
        if (response.IsSuccessStatusCode)
        {
            logger.Info("Response returned with status {Status}", response.StatusCode);
        }
        else
        {
            logger.Warn("Response returned with status {Status}", response.StatusCode);
        }
    }
}

相关问题