Recently I found that the HttpClient doesn’t change cookie value per request, and it will cache the value for 2 minutes after the first request which have set the cookie value sent.
Environment
- dotnet 5
- runtime image: mcr.microsoft.com/dotnet/aspnet:5.0
Description
I use typed client in our project and use HttpRequestMessage to set the cookie “user.token” in every request.
1 | public class MyHttpClient : IMyHttpClient |
Register MyHttpClient to the Denpency Injection provider.
1 | services.AddHttpClient<IMyHttpClient, MyHttpClient>(config => |
When I use CallAPI()
of MyHttpClient, I found the cookie doesn’t change value per request, and it will cache value for 2 minutes.
Why
HttpClient is just a container of HttpClientHandler
. If you trace the source code on Github you will see the code
1 | public HttpClient CreateClient(string name) |
When you are asking for HttpClient, HttpClientFactory will generate a HttpClient instance everytime and try to get HttpMessageHandler from the pool. Why HttpClientFactory maintains HttpMessageHandler pool for us? Because creating TCP connections are extremely expensive, so we should reuse it as we can as possible.
So multiple HttpClients will possibly use same HttpMessageHandler. HttpMessageHandler has Property named CookieContainer. It will store cookie value when you first time to set the value. So it will cause different requests using same cookie value until HttpMessageHandler expired.
Solution
There is a way to stop HttpMessageHandler using CookieContainer.
1 | services.AddHttpClient<IPortalShellClient, PortalShellHttpClient>(config => |
Then you can set cookie value per request now.