Вложенный Async вызывает HttpContext Null - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть проект WebAPI, который использует Entity Framework, и ниже приведены SaveChanges, которые я переопределяю для отслеживания метки времени и т. Д. Мне интересно, почему, когда я переместил AddAuditCustomField в дочерний метод, HttpContext стал нулевым.Я использую Audit.NET AuditDbContext.

        public override async Task<int> SaveChangesAsync()
        {

            AddAuditCustomField("url_endpoint",HttpContextHelper.GetUriEndpoint());
            return await SaveChangesAsync(true);
        }


        public async Task<int> SaveChangesAsync(bool invokeEvent)
        {
            try
            {

            //Placing here will be NULL 
           //AddAuditCustomField("url_endpoint",HttpContextHelper.GetUriEndpoint());
            return await SaveChangesAsync(true);
                if (invokeEvent)
                    OnItemSaveChanges?.Invoke();
                AddTimestamps();

                return await base.SaveChangesAsync();
            }
            catch (DbEntityValidationException e)
            {
                throw;
            }
        }

Ниже приведен HttpContextHelper

namespace Test.Core.Helpers
{
    public class HttpContextHelper
    {
        public static  string GetUriEndpoint()
        {

            if (HttpContext.Current != null) return HttpContext.Current.Request.Url.AbsoluteUri;

            if (WebOperationContext.Current != null)
                return WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString;

            if( HttpContextProvider.Current!=null) return HttpContextProvider.Current.Request.Url.AbsoluteUri;

            return null;
        }
    }
}

Контроллер, которым я его называю

  var entity = new Entity
                {
                    Name = "test"
                };
                  Db.Entities.Add(entity);
                try
                {
                    await Db.SaveChangesAsync();
                }
                catch (Exception e)
                {
                    if (e.IsDuplicateIndexError())
                    {
                        LogUtil.Error(message);

                    }
                    throw;
                }

Читалкакой-то другой поток, и они заявили, что он работает Использование HttpContext.Current в WebApi опасно из-за асинхронности

И я нацеливаюсь на 4.7.1

1 Ответ

0 голосов
/ 08 января 2019

Если вы используете библиотеку Audit.NET, у вас уже должен быть IP-адрес и имя пользователя на объекте AuditEvent.Environment.Также имеется расширение Audit.WebApi для регистрации действий WebAPI, и его можно комбинировать с Audit.EntityFramework.

Также нет необходимости передавать или получать HttpContextна уровне контекста БД.Audit.NET уже предоставляет механизм для обогащения данных события аудита с помощью пользовательских действий , поэтому вы можете поместить код, который зависит от контекста HTTP, только на веб-уровне в код инициализации, например, в ваш WebAPIкод запуска (при условии, что вы используете asp.net core 2):

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    var svcProvider = services.BuildServiceProvider();
    // Add the Audit.NET custom action
    Audit.Core.Configuration.AddCustomAction(ActionType.OnScopeCreated, scope =>
    {
        // Additional information as a custom field
        var someData = svcProvider
            .GetService<IHttpContextAccessor>()
            .HttpContext.WhateverYouNeed;
        scope.Event.CustomFields["SomeData"] = someData;
    }
}
...