问题
When using Flurl.Http v1.2 we had the following code:
1. var cookieJar = new CookieContainer();
2. var url = baseUrl.AppendPathSegment("api/auth/login");
3. var client = url.EnableCookies();
4. ((HttpClientHandler)client.HttpMessageHandler).CookieContainer = cookieJar;
5. var result = await client.PostJsonAsync(new { UserName = userName, Password = password });
6. var cookies = cookieJar.GetCookies(new Uri(baseUrl));
7. _cookie = cookies[0];
After upgrading to v2.0.1 line 4 no longer compiles because client
is no longer an IFlurlClient
it's now an IFlurlRequest
, as per the release notes.
I noticed that IFlurlRequest
has a Client
property, so I changed line 4 to be:
4. ((HttpClientHandler)client.Client.HttpMessageHandler).CookieContainer = cookieJar;
That now compiles but fails at run-time with an InvalidOperationException:
This instance has already started one or more requests. Properties can only be modified before sending the first request.
I'm assuming that's because of the aggressive reuse of the underlying HttpClient. I added a line between 3 and 4 to create a new FlurlClient each time to ensure the instance could not have started a request.
1. var cookieJar = new CookieContainer();
2. var url = baseUrl.AppendPathSegment("api/auth/login");
3. var request = url.EnableCookies();
3.5 request.Client = new FlurlClient();
4. ((HttpClientHandler)request.Client.HttpMessageHandler).CookieContainer = cookieJar;
5. var result = client.PostJsonAsync(new { UserName = userName, Password = password }).Result;
6. var cookies = cookieJar.GetCookies(new Uri(baseUrl));
7. _cookie = cookies[0];
This now works again, but I'm not sure I'm doing this the correct way. Any feedback would be appreciated.
回答1:
You shouldn't need to manage CookieContainer
explicitly; Flurl makes working with cookies a lot simpler.
Generally you want to reuse HttpClient
instances as much as possible, and 2.0 does do this for you by default when you don't create FlurlClient
s explicitly, but in the case of persisting cookies over multiple calls you're probably going to want to manage FlurlClient
yourself, otherwise multiple threads could be reading/writing cookies on the same collection.
Still pretty easy. I think your whole example can be reduced to this:
using (var cli = new FlurlClient(baseUrl).EnableCookies()) {
await cli.Request("api/auth/login").PostJsonAsync(new {
UserName = userName,
Password = password });
_cookie = cli.Cookies.First().Value;
}
来源:https://stackoverflow.com/questions/47291981/getting-back-cookies-from-the-request-in-flurl-http-v2-0-1