我需要在我的网络请求中添加客户端证书,并尝试以这种方式实现它: Stackoverflow
在这个答案的最后,提出了“FlurlClient方式”。使用和配置FlurlClient而不是全局FlurlHttp配置。我试过这个,但它没有用。
我已经创建了一个新的 .NET Core 控制台应用程序来向您显示问题:
static void Main(string[] args)
{
/****** NOT WORKING *******/
try
{
IFlurlClient fc1 = new FlurlClient(url)
.ConfigureClient(c => c.HttpClientFactory = new X509HttpFactory(GetCert()));
fc1.WithHeader("User-Agent", userAgent)
.WithHeader("Accept-Language", locale);
dynamic ret1 = fc1.Url.AppendPathSegments(pathSegments).GetJsonAsync()
.GetAwaiter().GetResult();
}
catch
{
// --> Exception: 403 FORBIDDEN
}
/****** NOT WORKING *******/
try
{
IFlurlClient fc2 = new FlurlClient(url);
fc2.Settings.HttpClientFactory = new X509HttpFactory(GetCert());
fc2.WithHeader("User-Agent", userAgent)
.WithHeader("Accept-Language", locale);
dynamic ret2 = fc2.Url.AppendPathSegments(pathSegments).GetJsonAsync()
.GetAwaiter().GetResult();
}
catch
{
// --> Exception: 403 FORBIDDEN
}
/****** WORKING *******/
FlurlHttp.Configure(c =>
{
c.HttpClientFactory = new X509HttpFactory(GetCert());
});
dynamic ret = url.AppendPathSegments(pathSegments).GetJsonAsync()
.GetAwaiter().GetResult();
// --> OK
}
从链接的StackOverflow答案中复制X509HttpFactory
(但使用HttpClientHandler
代替WebRequestHandler
):
public class X509HttpFactory : DefaultHttpClientFactory
{
private readonly X509Certificate2 _cert;
public X509HttpFactory(X509Certificate2 cert)
{
_cert = cert;
}
public override HttpMessageHandler CreateMessageHandler()
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(_cert);
return handler;
}
}
因此,使用全局FlurlHttp配置正在运行,并且配置FlurlClient无法正常工作。为什么呢?
答案 0 :(得分:4)
这一切都归结为你所称的命令:
fc.Url
返回一个Url
对象,这只不过是一个字符串构建的东西。它没有对FlurlClient
的引用。 (这允许Flurl作为独立于Flurl.Http的URL构建库存在。)Url.AppendPathSegments
返回“this”Url
。Url.GetJsonAsync
是一种扩展方法,首先创建FlurlClient
,然后将其与当前Url
一起使用以进行HTTP调用。正如您所看到的,您在该流程的第1步中失去了对fc
的引用。 2种可能的解决方案:
<强> 1。首先构建URL,然后流畅地添加HTTP位:
url
.AppendPathSegments(...)
.ConfigureClient(...)
.WithHeaders(...)
.GetJsonAsync();
<强> 2。或者,如果要重用FlurlClient,请使用WithClient将其“附加”到URL:
var fc = new FlurlClient()
.ConfigureClient(...)
.WithHeaders(...);
url
.AppendPathSegments(...)
.WithClient(fc)
.GetJsonAsync();