1

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

MarkCo
  • 810
  • 2
  • 12
  • 29
  • 2
    "Correct" simply depends on your scenario. If this works and meets your needs, it is probably correct enough. – David L Aug 10 '21 at 21:29
  • @DavidL I gotcha, but is that the way its supposed to behave? As in when it first adds the username to the header, then redirecting to the next page it will not enter that if statement to add the header. Is that the way it should behave? Sorry I am new to the middleware process – MarkCo Aug 10 '21 at 21:41
  • Have you debugged your if statement, checking the headers collection to see if it looks the way you would expect? – David L Aug 10 '21 at 21:53
  • I do not see headers collection when debugging `httpContext.Request.Headers`, is it somewhere else? – MarkCo Aug 10 '21 at 22:07

1 Answers1

1

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

Jason Pan
  • 15,263
  • 1
  • 14
  • 29
  • Thank you! Whenever I do so, I noticed it will grab the previous username that was enter in the textbox regardless that the application has ended. So when the app first starts and hits the index page it will enter the `if(tempData.ContainsKey("username"))` which it should not since a username was not entered. Is there a way to clear the tempData when the app closes so that way it can start off on a clean slate instead of using the username that was last entered? – MarkCo Aug 11 '21 at 04:46
  • @MarkCo Why you don't use Session. I mean we can set a valid time for the username, and the next time the authentication expires, it will be removed. – Jason Pan Aug 11 '21 at 04:54
  • Session as in https://www.c-sharpcorner.com/UploadFile/ansh06031982/passing-data-using-viewdata-viewbag-tempdata-session-vari/ ? Please see the updated post so you can see the part I am talking about in that link – MarkCo Aug 11 '21 at 05:02
  • @MarkCo Thanks for your documentation, I already know the usage of Tempdata very well. – Jason Pan Aug 11 '21 at 05:10
  • @MarkCo It is recommended that you add time-sensitive parameters to the middleware to pass the data you want. – Jason Pan Aug 11 '21 at 05:12
  • Oh I was talking about the [Session] portion if that is what you meant, sorry I never heard of session. Just TempData... – MarkCo Aug 11 '21 at 05:14
  • How would I go about adding time-sensitive parameters to the middle to pass the data desired? – MarkCo Aug 11 '21 at 05:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235862/discussion-between-markco-and-jason-pan). – MarkCo Aug 11 '21 at 05:15
  • @MarkCo httpContext.Request.Headers.TryGetValue( CorrelationIdHeaderKey, out StringValues correlationIds) always equal false, right ? – Jason Pan Aug 11 '21 at 06:21
  • Yes it is always false, I noticed that when debugging it – MarkCo Aug 11 '21 at 13:24