HttpContext.Current имеет значение null при добавлении обработчика делегата - PullRequest
0 голосов
/ 24 марта 2019

В одном из моих проектов я добавил обработчик делегатов для регистрации входящих и исходящих запросов. Для ведения журнала я использую Nlog. Я генерировал уникальный идентификатор для каждого запроса, чтобы связать журналы с этим конкретным идентификатором. Это работало нормально для меня. Недавно я изменил свой код в обработчике и установил для HttpContext.Currnet.Item значение этого уникального идентификатора. Теперь я должен получить этот идентификатор и передать его внешнему Apis.

Проблема, с которой я столкнулся, находится внутри контроллера HttpContext.Current равен нулю. Я знаю, что является основной причиной. Это из-за handler.SendAsync, который сделает поток SynchronizationContext нулевым.

Я хочу передать HttpContext.Current моим текущим потокам.

Что я сделал:

Я установил ConfigureAwait (false) Я установил appsettings -> aspnet: UseTraskFriendlySynchronizationContext в true

но они не работают.

Я использую .net Framework 4.7.1

1 Ответ

0 голосов
/ 25 марта 2019

Спасибо @ Александр, После ваших комментариев я снова просмотрел свой код и обнаружил, что эта проблема не вызвана await base.SendAsync (), Infact Я вызывал внутренние методы с помощью 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);
        }
    }
}
...