diff --git a/TestAsyncLocalMiddleware/Infrastructure/ContextBuilder.cs b/TestAsyncLocalMiddleware/Infrastructure/ContextBuilder.cs index 3307a4a..50169bd 100644 --- a/TestAsyncLocalMiddleware/Infrastructure/ContextBuilder.cs +++ b/TestAsyncLocalMiddleware/Infrastructure/ContextBuilder.cs @@ -24,9 +24,12 @@ IDictionary> headers { var contextCollection = new Dictionary>(); - foreach (var kv in securityTokenAccessor.ContextItems) + if (securityTokenAccessor.ContextItems != null) { - contextCollection.Add(kv.Key, new[] { kv.Value.ToString() }); + foreach (var kv in securityTokenAccessor.ContextItems) + { + contextCollection.Add(kv.Key, new[] { kv.Value.ToString() }); + } } if (headers != null) diff --git a/TestAsyncLocalMiddleware/Infrastructure/ISecurityTokenAccessor.cs b/TestAsyncLocalMiddleware/Infrastructure/ISecurityTokenAccessor.cs index a4638ec..a5b36fe 100644 --- a/TestAsyncLocalMiddleware/Infrastructure/ISecurityTokenAccessor.cs +++ b/TestAsyncLocalMiddleware/Infrastructure/ISecurityTokenAccessor.cs @@ -7,6 +7,7 @@ public interface ISecurityTokenAccessor IDictionary ContextItems { get; + set; } } } \ No newline at end of file diff --git a/TestAsyncLocalMiddleware/Infrastructure/SecurityTokenAccessor.cs b/TestAsyncLocalMiddleware/Infrastructure/SecurityTokenAccessor.cs index b74f4d7..d9c806c 100644 --- a/TestAsyncLocalMiddleware/Infrastructure/SecurityTokenAccessor.cs +++ b/TestAsyncLocalMiddleware/Infrastructure/SecurityTokenAccessor.cs @@ -8,31 +8,38 @@ namespace TestAsyncLocalMiddleware.Infrastructure { public class SecurityTokenAccessor : ISecurityTokenAccessor { - private readonly AsyncLocal> _asyncLocalDictionary = new AsyncLocal>(); + private readonly AsyncLocal _asyncLocalDictionary = new AsyncLocal(); public IDictionary ContextItems { get { - var result = GetThreadLocal(); - if (result == null) + return _asyncLocalDictionary.Value?.Context; + } + set + { + var holder = _asyncLocalDictionary.Value; + if (holder != null) + { + // Clear current HttpContext trapped in the AsyncLocals, as its done. + holder.Context = null; + } + + if (value != null) { - result = new Dictionary(); - SetThreadLocal(result); + // Use an object indirection to hold the dictionary in the AsyncLocal, + // so it can be cleared in all ExecutionContexts when its cleared. + _asyncLocalDictionary.Value = new ContextHolder { Context = value }; } - return result; } } - private IDictionary GetThreadLocal() - { - return _asyncLocalDictionary.Value; - } + - private void SetThreadLocal(IDictionary contextItems) - { - _asyncLocalDictionary.Value = contextItems; - } + } + public class ContextHolder + { + public IDictionary Context; } } diff --git a/TestAsyncLocalMiddleware/Infrastructure/TokenAuthenticationMiddleware.cs b/TestAsyncLocalMiddleware/Infrastructure/TokenAuthenticationMiddleware.cs index ee2ea56..8838b2d 100644 --- a/TestAsyncLocalMiddleware/Infrastructure/TokenAuthenticationMiddleware.cs +++ b/TestAsyncLocalMiddleware/Infrastructure/TokenAuthenticationMiddleware.cs @@ -53,13 +53,16 @@ public async Task Invoke(HttpContext context, ILog log) /// private void PopulateTokenAccessor(IHeaderDictionary headers) { + var contextItems = new Dictionary(); //CorpId if (headers.ContainsKey(AuthCorpIdHeader)) - _securityTokenAccessor.ContextItems.Add(ContextBuilder.CorpIdHeader, headers[AuthCorpIdHeader].First()); + contextItems.Add(ContextBuilder.CorpIdHeader, headers[AuthCorpIdHeader].First()); // UserId if (headers.ContainsKey(AuthUserHeader)) - _securityTokenAccessor.ContextItems.Add(ContextBuilder.UserIdHeader, headers[AuthUserHeader].First()); + contextItems.Add(ContextBuilder.UserIdHeader, headers[AuthUserHeader].First()); + + _securityTokenAccessor.ContextItems = contextItems; } }