我有一个使用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
答案 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;
}
}