在我的一个项目中,我添加了委托处理程序来记录传入和传出请求。对于日志我正在使用Nlog。我根据请求将日志与此特定ID相关联,从而生成唯一ID。这对我来说很好。最近我在handler中修改了我的代码,并将HttpContext.Currnet.Item值设置为这个唯一的id。现在我应该得到这个id,并把它传递给外部的Apis。
我面临的问题是内部控制器HttpContext.Current为null。我知道主要根本原因是什么。这是因为handler.SendAsync,它将使线程SynchronizationContext为null。
我想将HttpContext.Current传递给我正在进行的线程。
我做了什么:
我设置了ConfigureAwait(false)我将appsettings - > aspnet:UseTraskFriendlySynchronizationContext设置为true
但这些都不起作用。
我正在使用.net框架4.7.1
感谢@Alexander,在您发表评论之后我再次审查了我的代码并发现此问题不是由await base.SendAsync()引起的,Infact我用异步调用内部方法,这破坏了HttpContext.Current。
以下是我的DelegatingHandler实现参考。在此之前,我定义了两个方法,即IncommingMessageAsync(),OutgoingMessageAsync as 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);
}
}
}