HttpContext.Current is null inside Identity Framework's methods

你说的曾经没有我的故事 提交于 2019-12-05 02:50:55

As you said, this occurs because of threading. The delegate runs in a different thread, making the HttpContext inaccessible.

You can move the variable outside of the delegate, making it a closure.

private void InitializeAudit()
{
    var octx = ((IObjectContextAdapter) this).ObjectContext;
    HttpContext context = HttpContext.Current;

    octx.SavingChanges +=
        (sender, args) =>
        {
            // context is not null
        };
}

You are using asp.net identity through owin, so one instance of the dbcontext is created per request, and you can get this reference from anywhere in the request pipeline.

nb. this is handy but i think the dbcontext shouldn't be accessed outside the manager. In asp.net identity design, only the manager should be aware of the store. I believe the dbcontext is exposed because several asp.net identity middleware have a dependance on it.

But, it could help resolve you problem:

Allow your custom dbcontext handler to be set outside the class:

public EventHandler SavingChangesEventHandler
        {
            set
            {
                (((System.Data.Entity.Infrastructure.IObjectContextAdapter)this).ObjectContext).SavingChanges += value;
            } 
        }

Declare a custom ActionFilter class and register it, then override OnActionExecuting:

Filtering in ASP.NET MVC https://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx

public class CustomizeAppDbcontextFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var dbcontext = HttpContext.GetOwinContext().Get<ApplicationDbContext>();    
        var currentuser = HttpContext.Current.User;

        dbcontext.SavingChangesEventHandler = (sender, args) =>
            {
                // use currentuser
            };  
    }    
}

you may need these using statements to be able to call the identity.owin extension methods:

using Microsoft.AspNet.Identity;

using Microsoft.AspNet.Identity.Owin;

You should be in the controller thread because OnActionExecuting is wrapping the controller action.

I did not test it, so it may need some polishing but the concept should work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!