Search code examples
c#asp.net-mvcasp.net-core-mvcmiddlewaretempdata

Pass username into headers using httpContext asp.net core mvc


I am wanting to pass a variable into headers in my middleware. In my controller I am using username to hold the value that was entered in View. Then I was thinking if I use TempData I could be pass the value of username to my middleware class and add it to the header. I noticed that after it finally enters the if statement ( if (tempData.ContainsKey("username"))) and adds the header. When I proceed to the next page, it will return back to the middleware... it will not enter the if statement and proceed on the next line correlationId = Guid.NewGuid().ToString();`. Is this the correct way to pass the variable in the middleware and add it to the header?

Controller:

  [HttpPost]
    public IActionResult AddressValidate(IFormCollection form)
    {
        // if radio button was checked, perform the following var request.

        // username

        string username = form["UserName"];
        TempData["username"] = username;
        TempData.Keep();

        string status = form["Status"];

        _logger.LogInformation("Current user logged in: {@Username}", username);
 
      ......

   return RedirectToAction("SecondIndex", "Second")         
}

Middleware:

  public class CorrelationIdMiddleware
    {
        private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
        private const string CorrelationIdHeaderKey = "X-Correlation-ID";
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;
        public CorrelationIdMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ITempDataDictionaryFactory tempDataDictionaryFactory)
        {
            _next = next ?? throw new ArgumentNullException(nameof(next));
            _logger = loggerFactory.CreateLogger<CorrelationIdMiddleware>();
            _tempDataDictionaryFactory = tempDataDictionaryFactory;
        }
        public async Task Invoke(HttpContext httpContext)
        {
            string correlationId = null;
            string userName;

            var tempData = _tempDataDictionaryFactory.GetTempData(httpContext);

  
            if (httpContext.Request.Headers.TryGetValue(
            CorrelationIdHeaderKey, out StringValues correlationIds))
            {
                correlationId = correlationIds.FirstOrDefault(k =>
                k.Equals(CorrelationIdHeaderKey));
                _logger.LogInformation("CorrelationId from Request Header: {@correlationId} ", correlationId);
            }
            else
            {
                if (tempData.ContainsKey("username"))
                {
                    userName = tempData["username"].ToString();
                    httpContext.Request.Headers.Add("X-username", userName);
                }

                correlationId = Guid.NewGuid().ToString();
                httpContext.Request.Headers.Add(CorrelationIdHeaderKey,
                correlationId);
                _logger.LogInformation("Generated CorrelationId: {@correlationId}", correlationId);
            }
            httpContext.Response.OnStarting(() =>
            {
                if (!httpContext.Response.Headers.
                TryGetValue(CorrelationIdHeaderKey,
                out correlationIds))
                    httpContext.Response.Headers.Add(
                    CorrelationIdHeaderKey, correlationId);
                return Task.CompletedTask;
            });
            await _next.Invoke(httpContext);
        }
    }

Session as in this?

enter image description here


Solution

  • You should write the logic code you write into the header in httpContext.Response.OnStarting. It works for me.

    enter image description here

    enter image description here