【问题标题】:How to preserve headers in the Flurl HttpClient如何在 Flurl HttpClient 中保留标头
【发布时间】:2015-02-13 15:30:34
【问题描述】:

我在 .NET Http 客户端上使用 Furl.Http 包装器。对于每个请求,我的 API 都需要发送一个 User-Agent 和一个 Authorization 标头。

我想设置一次,而不是每次都声明。

我认为我能够做的是创建 FlurlClient 的实例并在其上设置标头,然后在每个请求之前 ResetToRoot,如以下示例代码所示:

    var fc = new FlurlClient();
    fc.WithHeader("User-Agent", "Keep/1.0");
    var tokenModel = await
        "https://app.tempuri.com".AppendPathSegment("auth")
        .WithClient(fc)
        .PostUrlEncodedAsync(new { username = "you", password = "secret"})
        .ReceiveJson<TokenModel>();

    fc.WithHeader("Authorization",
         string.Format("Token {0}",tokenModel.Token));                  

fc.Url.ResetToRoot();
    var userModel = await fc.Url
                          .AppendPathSegment("auth").GetJsonAsync<UserModel>();
    Console.WriteLine(userModel.Username);

但是,RestToRoot() 之后似乎不再发送标头。

这是设计使然吗?有没有更好的方法来确保在每个请求上发送这些标头?

【问题讨论】:

    标签: portable-class-library dotnet-httpclient flurl


    【解决方案1】:

    问题是倒数第二行。

    fc.Url...GetJsonAsync
    

    FlurlClient 具有对 Url 对象的引用,但反之亦然,因此当您调用 fc.Url 时,您实际上已经丢失了该引用,并且在幕后创建了一个新的 FlurlClient当您致电GetJsonAsync 时。这是设计使然,Flurl.Url 是核心 Flurl 库中的一个简单构建器类,可以独立于 Flurl.Http 使用。

    我会这样做:

    var url = "https://app.tempuri.com";
    
    using (var fc = new FlurlClient().WithHeader("User-Agent", "Keep/1.0")) {
        var tokenModel = await url
            .AppendPathSegment("...")
            .WithClient(fc)
            .PostUrlEncodedAsync(new { username = "you", password = "secret"})
            .ReceiveJson<TokenModel>();
    
        fc.WithHeader("Authorization",
            string.Format("Token {0}",tokenModel.Token));                  
    
        var userModel = await url
            .AppendPathSegment("...")
            .WithClient(fc)
            .GetJsonAsync<UserModel>();
    
        Console.WriteLine(userModel.Username);
    }
    

    几个注意事项:

    1. 请注意,您在每个 HTTP 调用中附加FlurlClient
    2. 这里的url变量只是一个字符串,所以不需要调用ResetToRoot
    3. using 语句在这里不是绝对必需的,但它是一种很好的做法。

    【讨论】:

      【解决方案2】:

      还有一种替代方法也可以。对于每个连续的 HTTP 调用,首先修改fc.Url,然后使用fc 进行调用:

      fc.Url.ResetToRoot().AppendPathSegment(...);
      var x = await fc.GetJsonAsync<T>();
      

      在这种情况下,您需要调用ResetToRoot,而不是WithClient。流利的链在这里被打破,但你可能会发现它更具可读性。无论哪种方式都有效,只是个人喜好问题。

      【讨论】:

        猜你喜欢
        • 2017-06-02
        • 1970-01-01
        • 2013-04-21
        • 1970-01-01
        • 2019-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-13
        相关资源
        最近更新 更多