6

使用 Flurl.Http v1.2 时,我们有以下代码:

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];

根据发行说明,升级到 v2.0.1 后,第 4 行不再编译,因为client它不再是 an ,IFlurlClient它现在是 an 。IFlurlRequest

我注意到它IFlurlRequest有一个Client属性,所以我将第 4 行更改为:

4. ((HttpClientHandler)client.Client.HttpMessageHandler).CookieContainer = cookieJar;

现在编译但在运行时失败并出现 InvalidOperationException:

此实例已启动一个或多个请求。只能在发送第一个请求之前修改属性。

我假设这是因为底层 HttpClient 的积极重用。我在 3 和 4 之间添加了一行,以每次创建一个新的 FlurlClient 以确保实例无法启动请求。

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];

这现在再次起作用,但我不确定我是否以正确的方式这样做。对于任何反馈,我们都表示感谢。

4

1 回答 1

9

您不需要CookieContainer明确管理;Flurl 使使用 cookie 变得更加简单。

一般来说,您希望HttpClient尽可能多地重用实例,当您没有FlurlClient显式创建 s 时,默认情况下 2.0 会为您执行此操作,但如果在多次调用中持久化 cookie,您可能需要FlurlClient自己管理,否则多个线程可能会在同一个集合上读取/写入 cookie。

还是很容易的。我认为您的整个示例可以简化为:

using (var cli = new FlurlClient(baseUrl).EnableCookies()) {
    await cli.Request("api/auth/login").PostJsonAsync(new {
        UserName = userName,
        Password = password });
    _cookie = cli.Cookies.First().Value;
}
于 2017-11-14T17:55:44.630 回答