嵌套异步导致HttpContext为空

时间:2018-12-07 19:27:05

标签: c# entity-framework audit.net

我有一个使用Entity Framework的WebAPI项目,以下是我为了监视时间戳等而覆盖的SaveChanges。我想知道为什么当我将AddAuditCustomField移入子Method时,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;
                }

一直在阅读其他一些线程,他们说它正在工作 Using HttpContext.Current in WebApi is dangerous because of async

我的目标是4.7.1

1 个答案:

答案 0 :(得分:0)

如果您正在使用Audit.NET库,则AuditEvent.Environment对象上应该已经具有IP和用户名。还有一个扩展名Audit.WebApi,用于记录WebAPI操作,并且可以与Audit.EntityFramework结合使用。

也无需传递或获取Db上下文层上的HttpContext。 Audit.NET已经提供了一种通过custom actions来丰富审核事件数据的机制,因此您可以将依赖于HTTP上下文的代码仅放在初始化代码的Web层上,例如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;
    }
}