代码之家  ›  专栏  ›  技术社区  ›  Craig W.

正在Flurl中从请求中取回Cookie。Http v2.0.1

  •  6
  • Craig W.  · 技术社区  · 7 年前

    使用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 不再是 IFlurlClient 现在是一个 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];
    

    现在这又起作用了,但我不确定我的方法是否正确。如有任何反馈,我们将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  9
  •   Todd Menier    7 年前

    你不需要管理 CookieContainer 明确地Flurl使使用Cookie变得更加简单。

    通常,您希望重用 HttpClient 实例,默认情况下,当您不创建 FlurlClient s显式,但在多个调用上持久化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;
    }