如何在 Flurl HttpClient 中保留 headers
How to preserve headers in the Flurl HttpClient
我在 .NET Http 客户端上使用 Furl.Http 包装器。对于每个请求,我的 API 都需要发送 User-Agent 和授权 header。
我想设置一次,而不是每次都要声明。
我认为我可以做的是创建一个 FlurlClient 实例并在其上设置 headers,然后在每个请求之前设置 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()
之后,header 似乎不再发送。
这是设计使然吗?是否有更好的方法来确保这些 header 被发送到每个请求?
问题是倒数第二行。
fc.Url...GetJsonAsync
FlurlClient
有一个对 Url
对象的引用,但反之则不然,所以当你调用 fc.Url
时,你实际上已经丢失了那个引用和一个新的FlurlClient
是在您调用 GetJsonAsync
时在幕后创建的。这是设计使然 Flurl.Url
是核心 Flurl 库中的一个简单构建器 class,可以独立于 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);
}
几个注意事项:
- 请注意,您在每个 HTTP 调用中附加
FlurlClient
。
- 这里的
url
变量只是一个字符串,所以不需要调用ResetToRoot
.
using
声明在这里不是绝对必需的,但这是一个很好的做法。
还有一种替代方法也可以。对于每个连续的 HTTP 调用,首先修改 fc.Url
,然后使用 fc
进行调用:
fc.Url.ResetToRoot().AppendPathSegment(...);
var x = await fc.GetJsonAsync<T>();
在这种情况下,您需要调用 ResetToRoot
而不是 WithClient
。 fluent 链在这里被打破了,但你可能会发现它更具可读性。哪种方式都行,只是个人喜好问题。
我在 .NET Http 客户端上使用 Furl.Http 包装器。对于每个请求,我的 API 都需要发送 User-Agent 和授权 header。
我想设置一次,而不是每次都要声明。
我认为我可以做的是创建一个 FlurlClient 实例并在其上设置 headers,然后在每个请求之前设置 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()
之后,header 似乎不再发送。
这是设计使然吗?是否有更好的方法来确保这些 header 被发送到每个请求?
问题是倒数第二行。
fc.Url...GetJsonAsync
FlurlClient
有一个对 Url
对象的引用,但反之则不然,所以当你调用 fc.Url
时,你实际上已经丢失了那个引用和一个新的FlurlClient
是在您调用 GetJsonAsync
时在幕后创建的。这是设计使然 Flurl.Url
是核心 Flurl 库中的一个简单构建器 class,可以独立于 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);
}
几个注意事项:
- 请注意,您在每个 HTTP 调用中附加
FlurlClient
。 - 这里的
url
变量只是一个字符串,所以不需要调用ResetToRoot
. using
声明在这里不是绝对必需的,但这是一个很好的做法。
还有一种替代方法也可以。对于每个连续的 HTTP 调用,首先修改 fc.Url
,然后使用 fc
进行调用:
fc.Url.ResetToRoot().AppendPathSegment(...);
var x = await fc.GetJsonAsync<T>();
在这种情况下,您需要调用 ResetToRoot
而不是 WithClient
。 fluent 链在这里被打破了,但你可能会发现它更具可读性。哪种方式都行,只是个人喜好问题。