c# - HttpContext.Current is null inside Identity Framework's methods -


i using asp.net mvc 5 , identity framework. when call usermanager.updateasync(...) eventhandlers on applicationdbcontext() savechanges run. here using httpcontext.current different purposes (logging , auditing) must current user. whole method runs in worker thread, , here httpcontext.current null.

the biggest problem usermanager's "sync" methods wrappers around async version, calls serialized, methods (and eventhandlers) still run in different worker thread.

please note issue has nothing async/await context. in controller after await (or calling 'sync' version) have correct httpcontext, controller's method continuing in other thread. that's fine.

so problem inside async worker run in both "sync" , async versions. think understanding phenomena (but not happy fake 'sync' method versions, real sync methods not exhibit issue.) not know how deal/workaround it.

[btw: not more natural implement usermanager's operarations simple pure sync versions, wrap them async multithreaded wrappers?. if continue async fashion without thinking invent async assignment operator. costs me dozens of hours (just issue), , costs worldwide zillion dollars, sure in many cases less return price.]

bonus: talking usermanager which's impact pretty marginal, same principles , issues can apply out of box library (black box you) authors not implement sync versions , or not care controller thread's context. ef, not marginal... , di containers instantiation infrastructure "request scope" or "session scope". surely misbehave if resolving occurs in thread no httpcontext.current. refreshed sendgrid nuget, , (as breaking change) deliver() method gone, , deliverasync() existing...

i have safe reliable way, how can access httpcontext inside worker logging , audit purposes.

sample code, controller 'sync' version:

[acceptverbs(httpverbs.post)] public virtual actionresult edit(applicationuser user) {     // validation etc     // update() seems poor wrapper around async version, still uses worker thread.     var result = usermanager.update(user);     // note: httpcontext correct here not async/await problem      // error handling, creating actionresult etc. } 

sample code, controller async version:

[acceptverbs(httpverbs.post)] public virtual async task<actionresult> edit(applicationuser user) {     // validation etc     var result = await usermanager.updateasync(user);     // note: httpcontext correct here not async/await problem      // error handling, creating actionresult etc. } 

and event handler httpcontext null:

public applicationdbcontext() : base("defaultconnection", false) {     initializeaudit(); }  private void initializeaudit() {     var octx = ((iobjectcontextadapter) this).objectcontext;      octx.savingchanges +=         (sender, args) =>         {             // httpcontext.current null here         }; } 

any ideas?

as said, occurs because of threading. delegate runs in different thread, making httpcontext inaccessible.

you can move variable outside of delegate, making closure.

private void initializeaudit() {     var octx = ((iobjectcontextadapter) this).objectcontext;     httpcontext context = httpcontext.current;      octx.savingchanges +=         (sender, args) =>         {             // context not null         }; } 

Comments