0

我在 .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()不再发送标头之后。

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

4

2 回答 2

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声明在这里不是绝对必需的,但它是一种很好的做法。
于 2015-02-13T16:16:17.730 回答
1

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

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

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

于 2015-02-13T16:41:31.227 回答