19.Ⅲ 常见问题
📝 模块更新日志
- 新特性
-
HTTP远程请求UriBuilder配置操作 4.9.8.45 ⏱️2026.04.19 56be6c6 -
HTTP声明式请求支持面向对象继承 4.9.8.42 ⏱️2026.04.17 b00f2b9 -
HTTP远程请求支持设置永不超时 4.9.8.21 ⏱️2026.03.09 92e0283 -
HTTP远程请求支持发送不进行URL编码的表单数据 4.9.8.15 ⏱️2026.02.09 f0104ef -
HTTP远程请求声明式请求支持Action<HttpRequestMessage>冻结参数 4.9.7.244 ⏱️2026.01.09 d9fce11 -
HTTP远程请求支持HttpRequestBuilder统一配置器IHttpRequestBuilderConfigurer4.9.7.244 ⏱️2026.01.09 d9fce11 -
HTTP远程请求支持提供从互联网URL地址下载文件流配置HttpClient和HttpRequestMessage实例 4.9.7.235 ⏱️2025.12.27 a723ae5 -
HTTP远程请求设置请求标头和Cookie支持配置参数 4.9.7.231 ⏱️2025.12.19 541fadd -
HTTP远程请求支持指定网卡IP地址请求 4.9.7.230 ⏱️2025.12.19 904705d -
HTTP远程请求HttpBuilder静态类,用于简化HttpRequestBuilder名称过长问题 4.9.7.222 ⏱️2025.12.08 c0b6c77 -
HTTP远程请求分析日志支持颜色高亮 4.9.7.217 ⏱️2025.12.03 29b9348 -
HTTP远程请求支持设置JSON响应反序列化包装器 4.9.7.214 ⏱️2025.11.26 f046b4d ebe71f9 -
HTTP远程请求支持在未配置日志服务时设置日志回退输出委托 4.9.7.213 ⏱️2025.11.26 17ac155 -
HTTP远程请求在设置JSON数据时支持传入JsonSerializerOptions对象 4.9.7.208 ⏱️2025.11.16 c97b467 -
HTTP远程请求支持自动修复无效的响应字符编码 4.9.7.202 ⏱️2025.11.13 35530e8 -
HTTP远程请求支持表单名称命名策略或自定义转换器 4.9.7.137 ⏱️2025.11.07 6c175a8 -
HTTP远程请求断言功能 4.9.7.137 ⏱️2025.11.07 c044b87 -
HTTP远程请求默认启用响应内容gzip、deflate和brotli自动解压 4.9.7.137 ⏱️2025.11.07 e9b10ac -
HTTP远程请求请求分析工具Profiler(enabled)别名方法:Debugger([enabled])4.9.7.137 ⏱️2025.11.07 c044b87 -
HTTP远程请求支持添加动态URL参数(请求时求值)4.9.7.131 ⏱️2025.10.17 a162c8d -
HTTP远程请求压力测试支持便捷禁用HTTP缓存 4.9.7.131 ⏱️2025.10.17 a162c8d -
HTTP远程请求支持配置多线程下载文件 4.9.7.123 ⏱️2025.09.16 10bddc9 -
HTTP远程请求支持将XML字符串转换为类型对象 4.9.7.123 ⏱️2025.09.16 41746d2 -
HTTP远程请求构建器实例支持When条件构建 4.9.7.100 ⏱️2025.07.22 651b4d5 -
HTTP远程请求扩展功能构建器WithRequest(Action<HttpRequestBuilder>)方法 4.9.7.95 ⏱️2025.07.10 4615670 -
HTTP远程请求声明式[MultipartObject]特性 4.9.7.94 ⏱️2025.07.09 7e52e9c -
HTTP远程请求支持Unix epoch日期格式 4.9.7.77 ⏱️2025.05.31 ca9c94e -
HTTP远程请求URL参数格式化程序 4.9.7.70 ⏱️2025.05.23 e8b24b3 -
HTTP远程请求支持配置SocketsHttpHandler忽略SSL证书验证 4.9.7.63 ⏱️2025.05.16 042da35 -
HTTP远程请求支持配置请求超时发生时的回调操作 4.9.7.62 ⏱️2025.05.15 23a580d -
HTTP远程请求HttpRemoteClient静态类 4.9.7.58 ⏱️2025.05.02 86e9dbe -
HTTP远程请求HttpRemoteResult<TResult>解构函数(析构表达式)功能支持 4.9.7.53 ⏱️2025.04.28 e4dcc10 -
HTTP远程请求IHttpClientBuilder.ConfigureOptions(configure)扩展方法 4.9.7.51 ⏱️2025.04.26 33479e2 -
HTTP远程请求请求分析工具打印HttpClient Name项 4.9.7.51 ⏱️2025.04.26 33479e2 -
HTTP远程请求WithSuccessStatusCodeHandler方法支持设置请求成功状态码回调操作 4.9.7.47 ⏱️2025.04.20 cf7956e -
HTTP远程请求状态码处理程序支持~符号设置区间,如200~2994.9.7.47 ⏱️2025.04.20 cf7956e -
HTTP远程请求SetOmitContentType(omit)方法支持移除或保留请求内容的Content-Type4.9.7.44 ⏱️2025.04.17 4d98d60 -
HTTP远程请求支持从JSON字符串创建HttpRequestBuilder实例 4.9.7.41 ⏱️2025.04.14 580dd04 -
HTTP远程请求支持使用SuppressExceptions()和[SuppressExceptions]抑制请求异常 4.9.7.40 ⏱️2025.04.12 1a9bc7b -
HTTP远程请求支持设置单次请求的HTTP版本 4.9.7.40 ⏱️2025.04.12 1a9bc7b -
HTTP远程请求请求分析工具打印HTTP Version项 4.9.7.40 ⏱️2025.04.12 1a9bc7b -
HTTP远程请求HttpRemoteResult<TResult>类型Version属性(HTTP版本) 4.9.7.40 ⏱️2025.04.12 1a9bc7b -
HTTP远程请求支持设置请求来源地址 4.9.7.36 ⏱️2025.04.02 5d4a241 -
HTTP远程请求HttpRequestBuilder.AddAuthentication(string, string?)重载方法 4.9.7.33 ⏱️2025.03.25 f8a648a -
HTTP远程请求多部分表单AddFile(IFormFile)和AddFiles(IEnumerable<IFormFile>)扩展方法 4.9.7.31 ⏱️2025.03.24 6eb54e0 -
HTTP远程请求反序列化时支持Number和Boolean类型转String类型 4.9.7.29 ⏱️2025.03.23 489aa55 -
HTTP远程请求序列化时自动处理中文乱码问题 4.9.7.29 ⏱️2025.03.23 489aa55 -
HTTP远程请求进行JSON反序列化时支持非ISO 8601-1:2019标准的时间字符串 4.9.7.25 ⏱️2025.03.14 10de94b 3f3d619 -
HTTP远程请求支持为所有HttpClient客户端添加配置IHttpRemoteBuilder.ConfigureHttpClientDefaults(configure)4.9.7.22 ⏱️2025.03.04 cef4ca0 -
HTTP远程请求支持WithPathSegment[s]设置路径片段 4.9.7.21 ⏱️2025.03.03 7b3335e -
HTTP远程请求支持为所有HttpClient客户端启用请求分析工具IHttpRemoteBuilder.AddProfilerDelegatingHandler()4.9.7.18 ⏱️2025.03.01 b6ba52b -
HTTP远程请求支持WebService(SOAP)支持 4.9.7.15 ⏱️2025.02.27 479073a -
HTTP远程请求AddProfilerDelegatingHandler(this IHttpClientBuilder builder, bool disableInProduction)重载方法 4.9.7.13 ⏱️2025.02.26 5ef4b13 -
HTTP远程请求Server-Sent Events支持任意HttpMethod4.9.7.13 ⏱️2025.02.26 caa2aca -
HTTP远程请求获取响应标头Set-Cookie扩展方法 4.9.7.11 ⏱️2025.02.24 62737cf -
HTTP远程请求支持设置请求分析工具触发委托 4.9.7.10 ⏱️2025.02.22 82b4d81 -
HTTP远程请求ConfigureOptions支持解析服务的重载方法 4.9.7.9 ⏱️2025.02.20 dabbc47 -
HTTP远程请求HttpRemoteOptions选项FallbackBaseAddress属性,支持回退请求基地址设置 4.9.7.9 ⏱️2025.02.20 dabbc47 -
HTTP远程请求HttpRemoteResult类型Server属性 4.9.7.9 ⏱️2025.02.20 5b1c181 -
HTTP远程请求HttpRequestMessage克隆扩展方法 4.9.7.8 ⏱️2025.02.18 abd61c8 -
HTTP远程请求[Forward]转发特性支持 4.9.7 ⏱️2025.01.23 023166b -
HTTP远程请求配置参数支持 4.9.7 ⏱️2025.01.23 023166b -
HTTP远程请求转发支持忽略请求或响应标头 4.9.7 ⏱️2025.01.23 023166b -
HTTP远程请求重定向支持相对路径 4.9.6.21 ⏱️2024.12.28 17df0c4 -
HTTP远程请求内置自动重定向处理流程 4.9.6.20 ⏱️2024.12.27 4998e13 -
HTTP远程请求HttpRemoteOptions选项AllowAutoRedirect和MaximumAutomaticRedirections配置 4.9.6.20 ⏱️2024.12.27 4998e13 -
HTTP远程请求WithCookie(cookieHeaderValue)重载方法 4.9.6.18 ⏱️2024.12.25 80394dc -
HTTP远程请求默认无配置支持HTTP/1.0和HTTP/1.1的服务器接口 4.9.6.16 ⏱️2024.12.17 61afe9a -
HTTP远程请求支持设置请求基地址功能 4.9.6.15 ⏱️2024.12.10 187a178 -
HTTP远程请求在添加表单项内容时支持预置操作 4.9.6.12 ⏱️2024.12.06 e610e32 -
HTTP远程请求在非依赖注入环境中支持打印请求分析工具内容 4.9.6.12 ⏱️2024.12.06 e610e32 -
HTTP远程请求支持声明式设置HttpRequestMessage请求属性特性 4.9.6.11 ⏱️2024.12.04 8306cf0 -
HTTP远程请求支持配置禁用请求分析工具委托 4.9.6.7 ⏱️2024.12.02 250ea66 -
HTTP远程请求支持启用性能优化支持 4.9.6.6 ⏱️2024.12.01 b7ad81b -
HTTP远程请求支持设置自动Host标头 4.9.6.6 ⏱️2024.12.01 b7ad81b -
HTTP远程请求DigestCredentials摘要身份认证支持 4.9.6.5 ⏱️2024.12.01 3298c02 -
HTTP远程请求FileTypeMapper文件MIME类型映射类 4.9.6.4 ⏱️2024.11.29 6782110 -
HTTP远程请求支持带应用速率限制的流 4.9.6.3 ⏱️2024.11.28 f281c32 -
HTTP远程请求支持特定需验证Content-Type的服务器程序 4.9.6.3 ⏱️2024.11.28 f281c32 -
HTTP远程请求支持配置请求分析工具日志级别 4.9.6.3 ⏱️2024.11.28 f281c32 -
HTTP远程请求支持全局配置HttpRemoteOptions配置 4.9.6.2 ⏱️2024.11.28 b60c996 -
HTTP远程请求支持配置查询参数是否忽略空值ignoreNullValues4.9.6.2 ⏱️2024.11.28 b60c996 -
HTTP远程请求MultipartFile添加文件类型 4.9.6.1 ⏱️2024.11.27 590cd5e -
HTTP远程请求WithStatusCodeHandler支持包含比较符号类型状态码 4.9.6.1 ⏱️2024.11.27 590cd5e -
HTTP远程请求AddHttpDeclarativeExtractorsFromAssemblies批量注册HTTP声明式提取器 4.9.6.1 ⏱️2024.11.27 590cd5e
-
- 突破性变化
- 问题修复
-
HTTP远程请求启用请求分析日志在Blazor应用同步请求中出现死锁问题 4.9.8.46 ⏱️2026.04.19 bfa8579 -
HTTP远程请求获取代理接口特性列表时未递归查找子特性 4.9.8.44 ⏱️2026.04.18 7b0098d -
HTTP远程请求添加泛型类型的声明式接口出现异常问题 4.9.8.42 ⏱️2026.04.17 b00f2b9 -
HTTP远程请求下载文件时若服务器未设置Content-Length导致下载失败问题 4.9.8.36 ⏱️2026.04.09 d904e8d -
HTTP远程请求转发HttpContext时不能转发Accept-Language问题 4.9.8.31 ⏱️2026.03.31 #IHTVU9 1f67681 -
HTTP远程请求分析工具打印超过2GB文件出现异常问题 4.9.8.2 ⏱️2026.01.24 600d02a -
HTTP远程请求在处理重定向时没有移除路径片段问题 4.9.8.1 ⏱️2026.01.22 288facb -
HTTP远程请求设置基地址不支持路径参数和配置参数问题 4.9.7.232 ⏱️2025.12.22 5252bbd -
HTTP远程请求分析工具存在重复打印问题 4.9.7.219 ⏱️2025.12.03 82091b4 -
HTTP远程请求分析日志打印表单数据不全问题 4.9.7.217 ⏱️2025.12.03 5bce378 -
HTTP远程请求分析日志不打印HttpClient默认配置请求头问题 4.9.7.217 ⏱️2025.12.03 fd0eedc -
HTTP远程请求克隆HttpRequestMessage丢失Options属性问题 4.9.7.215 ⏱️2025.11.26 bf38601 -
HTTP远程请求当上游服务器响应未携带Content-Type标头时,引发的空引用异常问题 4.9.7.210 ⏱️2025.11.18 48eae77 -
HTTP远程请求转发HttpContext内容时,部分状态码的响应正文丢失的问题 4.9.7.210 ⏱️2025.11.18 48eae77 -
HTTP远程请求静态类HttpRemoteClient多线程死锁问题 4.9.7.137 ⏱️2025.11.07 c044b87 -
HTTP远程请求解析响应Content-Disposition标头文件名出现中文乱码问题 4.9.7.124 ⏱️2025.09.16 183cb5e -
HTTP远程请求进行文件上传下载时控制台进度条不能自适应问题 4.9.7.116 ⏱️2025.09.02 47250ef -
HTTP远程声明式请求存在并发线程安全问题 4.9.7.115 ⏱️2025.08.31 0a5e57f #ICVKHB -
HTTP远程请求文件下载解析响应标头时文件名存在前后双引号问题 4.9.7.113 ⏱️2025.08.29 5e92eab -
HTTP远程请求转发HttpContext丢失Content-Type问题 4.9.7.109 ⏱️2025.08.14 9aaf17c -
HTTP远程请求转发HttpContext时出现禁用缓存无效问题 4.9.7.104 ⏱️2025.07.24 3a386fa -
HTTP远程请求中无法通过表单方式发送MultipartFile类型属性的问题 4.9.7.93 ⏱️2025.07.05 30c853d -
HTTP远程请求上传文件时,未配置文件名导致服务端无法正常接收文件的问题(若未指定文件名,默认将文件名设置为Unnamed_xxxxxxxxx) 4.9.7.93 ⏱️2025.07.05 30c853d -
HTTP远程请求分析工具在打印二进制内容时,若包含退格符可能导致输出不完整的问题 4.9.7.93 ⏱️2025.07.05 30c853d -
HTTP远程请求中配置超时时间的问题,并明确了超时后抛出的异常类型 4.9.7.90 ⏱️2025.06.25 679319d -
HTTP远程请求转换HttpContext时不能篡改HttpContent(Body)问题 4.9.7.89 ⏱️2025.06.20 ca7bfb5 -
HTTP远程请求分析工具不支持Blazor WebAssembly应用问题 4.9.7.69 ⏱️2025.05.22 c257ed0 -
HTTP远程请求请求分析工具手动打印出现格式错乱问题 4.9.7.52 ⏱️2025.04.27 14261e4 - 因
v4.9.7.49版本导致HTTP远程请求反序列化出现内存溢出(OOM)问题 4.9.7.50 ⏱️2025.04.25 4cf7375 406ff44 -
HTTP远程请求当请求的路径末尾包含/时被自动移除问题 4.9.7.45 ⏱️2025.04.17 5b18955 -
HTTP远程请求无法通过RemoveHeaders移除User-Agent问题 4.9.7.44 ⏱️2025.04.17 4d98d60 -
HTTP远程请求在强制启用IPv4时,若请求地址为IP地址时出现的异常问题 4.9.7.28 ⏱️2025.03.23 1d57a07 -
HTTP远程请求在解析URL参数若参数值出现多个=时导致解析失败问题 4.9.7.24 ⏱️2025.03.13 5c9270f -
HTTP远程请求在未设置查询参数且设置了移除查询参数列表时无效 4.9.7.21 ⏱️2025.03.03 7b3335e -
HTTP远程请求文件上传下载、长轮询和Server-Sent Events错误处理CancellationToken问题 4.9.7.16 ⏱️2025.02.28 21c1f06 -
HTTP远程请求客户端配置的基地址时出现空引用异常 4.9.7.16 ⏱️2025.02.28 21c1f06 -
HTTP远程请求分析工具未打印实际未成功但确保请求为成功的请求的问题 4.9.7.10 ⏱️2025.02.22 82b4d81 -
HTTP远程请求重定向操作错误的处理请求方法和请求体问题 4.9.7.2 ⏱️2025.01.26 c326cf3 -
HTTP远程请求转发HttpContext文件出现文件已损坏问题 4.9.7.1 ⏱️2025.01.23 e90a08c -
HTTP远程请求遇重定向时可能出现重复拼接查询参数问题 4.9.7 ⏱️2025.01.23 0e64da5
-
- 其他更改
-
HTTP远程请求文件下载传输进度的通知频率 4.9.8.37 ⏱️2026.04.11 49223d6 -
HTTP远程请求超时时间,支持设置为null4.9.8.22 ⏱️2026.03.09 537400c -
HTTP远程请求构建器的.SetOnPreSendRequest方法,支持多次调用 4.9.7.244 ⏱️2026.01.09 e42e6b0 - 简化
HTTP远程请求静态类 HttpRemoteClient 自定义配置 4.9.7.221 ⏱️2025.12.06 ca3d6f6 -
HTTP远程请求发送文本内容不支持设置Content-Type问题 4.9.7.218 ⏱️2025.12.03 9d6cdd1 -
HTTP远程请求日志系统,方便生产环境准确定位错误 4.9.7.212 ⏱️2025.11.26 c40570b -
HTTP远程请求WebSocket客户端构造函数选项参数 4.9.7.130 ⏱️2025.10.15 ca85e8e - 改进
HTTP远程请求文件下载功能,新增FileTransferResult返回值 4.9.7.128 ⏱️2025.09.30 9311ee3 04010e2 - 改进
HTTP远程请求文件上传和下载控制台进度条时间格式 4.9.7.117 ⏱️2025.09.02 665a453 -
HTTP远程请求文件上传和下载打印到控制台进度条效果 4.9.7.114 ⏱️2025.08.29 3204e72 -
HTTP远程请求设置多部分表单方法(重载) 4.9.7.99 ⏱️2025.07.19 60b9260 -
HTTP远程请求分析工具自动处理Unicode转义 4.9.7.48 ⏱️2025.04.23 f0a01d6 -
HTTP远程请求分析工具,支持打印请求和响应内容的大小 4.9.7.47 ⏱️2025.04.20 cf7956e -
HTTP远程请求默认的User-Agent为Edge浏览器(版本133)的User-Agent一致 4.9.7.18 ⏱️2025.03.01 b6ba52b -
HTTP远程请求长轮询属性(事件)类型,由Func<HttpResponseMessage, Task>?->Func<HttpResponseMessage, CancellationToken, Task>4.9.7.17 ⏱️2025.02.28 050e64f -
HTTP远程请求ServerSentEvents的onMessage属性类型,由Func<ServerSentEventsData, Task>?->Func<ServerSentEventsData, CancellationToken, Task>4.9.7.14 ⏱️2025.02.26 5ef4b13 -
HTTP远程请求自动设置Host请求标头为false,即默认不启用 4.9.6.20 ⏱️2024.12.27 4998e13 -
HTTP远程请求默认启用自动设置请求Host标头 4.9.6.16 ⏱️2024.12.17 61afe9a -
HTTP远程请求提交表单数据时默认设置Boundary4.9.6.16 ⏱️2024.12.17 61afe9a -
HTTP远程请求RateLimitedStream带应用速率限制的流,基于令牌桶算法 4.9.6.10 ⏱️2024.12.03 f0ee8af -
HTTP远程请求分析工具性能,打印内容时默认只输出10KB内容 4.9.6.9 ⏱️2024.12.02 88afe64 -
HTTP远程请求分析工具,提供请求内容和响应内容打印 4.9.6.7 ⏱️2024.12.02 250ea66 -
HTTP远程请求分析工具,提供更多细节打印 4.9.6.4 ⏱️2024.11.29 6782110
-
以下内容仅适用于 Furion 4.9.6+ 版本,且不支持 .NET8 以下版本。
19.28 常见问题
这里汇总了一些发送 HTTP 远程请求时可能遇到的常见问题。
19.28.1 忽略 SSL 证书验证
若发送 HTTP 远程请求过程中出现 The SSL connection could not be established, see inner exception. 的证书错误问题,您可以通过添加以下配置来忽略 SSL 证书验证:
// 默认客户端配置
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
// 忽略 SSL 证书验证
ServerCertificateCustomValidationCallback = HttpRemoteUtility.IgnoreSslErrors,
SslProtocols = HttpRemoteUtility.AllSslProtocols
});
// 若使用 SocketsHttpHandler,可以通过以下配置来忽略 SSL 证书验证
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler()
{
SslOptions = new SslClientAuthenticationOptions
{
// 忽略 SSL 证书验证
RemoteCertificateValidationCallback = HttpRemoteUtility.IgnoreSocketSslErrors,
EnabledSslProtocols = HttpRemoteUtility.AllSslProtocols
},
});
除了可以在全局配置中忽略 SSL 证书验证外,您还可以通过 SetHttpClientProvider 方法为单次请求单独设置忽略 SSL 证书验证。示例代码如下:
HttpRequestBuilder.Get("https://furion.net/")
.SetHttpClientProvider(() => (new HttpClient(new HttpClientHandler
{
// 忽略 SSL 证书验证
ServerCertificateCustomValidationCallback = HttpRemoteUtility.IgnoreSslErrors,
SslProtocols = HttpRemoteUtility.AllSslProtocols
}), client => client.Dispose()));
19.28.2 强制 IPv4 或 IPv6 请求
通过配置 SocketsHttpHandler 的 ConnectCallback,可强制 HttpClient 使用指定 IP 版本或本地出口地址发起请求,适用于网络策略控制或多网卡环境,,以优化性能或满足网络要求。示例如下:
// 强制 IPv4
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
ConnectCallback = HttpRemoteUtility.IPv4ConnectCallback
});
// 强制 IPv6
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
ConnectCallback = HttpRemoteUtility.IPv6ConnectCallback
});
// 默认(自动选择)
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
ConnectCallback = HttpRemoteUtility.UnspecifiedConnectCallback
});
// 多网卡场景:指定本地出口 IPv4
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
ConnectCallback = (context, token) =>
HttpRemoteUtility.ConnectWithLocalIPv4(IPAddress.Parse("192.168.0.103"), context, token)
});
// 多网卡场景:指定本地出口 IPv6
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
ConnectCallback = (context, token) =>
HttpRemoteUtility.ConnectWithLocalIPv6(IPAddress.Parse("::1"), context, token)
});
19.28.3 重定向响应处理
在发送 HTTP 远程请求时,若目标服务器返回重定向响应(如 301 Moved Permanently、302 Found 等),框架默认会自动跟随重定向。为精确处理这些情况,可参考以下方案:
- 通过
HttpRemoteOptions全局启用或禁用自动重定向
在发送 HTTP 远程请求时,若目标服务器返回重定向响应(如 301 Moved Permanently、302 Found 等),框架默认会自动跟随重定向。要启用或禁用这一行为,可以通过以下配置进行设置:
services.AddHttpRemote(builder => {})
.ConfigureOptions(options =>
{
// 设置指示请求是否应遵循重定向响应,默认 true
options.AllowAutoRedirect = false;
// 设置请求所遵循的最大重定向数,默认 50 次
options.MaximumAutomaticRedirections = 50;
});
- 通过
HttpClient全局启用或禁用自动重定向
若希望或不希望 HttpClient 自动处理重定向,可通过配置 HttpClientHandler 或 SocketsHttpHandler 来启用或禁用此功能。
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
AllowAutoRedirect = true, // 允许自动重定向,默认为 true (允许)
MaxAutomaticRedirections = 20 // 设置最大重定向次数
});
若您希望完全禁用自动重定向功能,请确保同时配置以下代码段:
services.AddHttpRemote(builder => {})
.ConfigureOptions(options =>
{
options.AllowAutoRedirect = false;
});
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
AllowAutoRedirect = false
});
请注意,上述全局配置不仅会影响 HTTP 远程请求服务的重定向行为,同样也会作用于 HttpContext 中的重定向转发。
- 通过手动处理重定向
也可以检查响应状态码。若状态码在 300-399 范围内,表明为重定向状态码,此时可手动解析 Location 头,并使用该地址重新发送请求。
- 禁用
HttpClient的自动重定向功能
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
AllowAutoRedirect = false
});
- 手动管理重定向流程
var responseMessage = await httpRemoteService.GetAsync("https://furion.net/redirect");
// 检查响应消息是否包含重定向状态码
var statusCode = responseMessage.StatusCode;
// 通常应使用 while 循环来进行判断,因为可能涉及多次重定向
if (statusCode is HttpStatusCode.Ambiguous or HttpStatusCode.Moved or HttpStatusCode.Redirect or HttpStatusCode.RedirectMethod or HttpStatusCode.RedirectKeepVerb || (int)statusCode == 308)
{
// 获取重定向地址
var redirectUrl = responseMessage.Headers.Location;
if (redirectUrl != null)
{
// 用新的 URL 再次发送请求
response = await httpRemoteService.GetAsync(redirectUrl);
}
}
选择哪种方法取决于您的具体需求。如果你需要更细粒度地控制每个重定向过程,比如记录日志或执行特定逻辑,那么手动处理可能是更好的选择。如果只是简单地想要让客户端自动处理所有重定向,则开启自动重定向更加方便。
19.28.4 性能优化
为了提升应用通过 HTTP 客户端发送网络请求的性能,可以通过配置默认的 HTTP 头部来优化数据传输效率。框架提供了一键式配置方法,方便快速统一设置这些头部:
// 为默认客户端配置
services.AddHttpClient(string.Empty, client =>
{
// 启用性能优化
client.PerformanceOptimization();
});
除了使用全局 HttpClient 配置,您还可以为单次请求配置特定设置,如下所示:
HttpRequestBuilder.Get("https://furion.net/")
.PerformanceOptimization(); // 启用性能优化功能
启用性能优化后,请求将自动添加以下头部,以提升传输效率:
Accept:*/*(接受任意类型的响应内容)Accept-Encoding:gzip, deflate, br(支持的内容编码格式,以提高传输效率)Connection:keep-alive(保持连接,减少TCP连接建立和关闭的开销)
当需要返回 Stream 内容或进行 HttpContext 网页转发时,请勿启用此配置,因为流会因压缩而变得不可读,同时该配置也不适用于网页转发的场景。
19.28.5 设置默认 User-Agent
在发送 HTTP 请求时,若用户未指定 User-Agent 请求头,框架将默认使用 Edge 浏览器(版本 135)的 User-Agent。示例如下:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0
如需自定义默认 User-Agent,可通过以下方式实现:
全局配置:
// 配置默认客户端的 User-Agent
services.AddHttpClient(string.Empty, client =>
{
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0");
});
单次请求设置:
HttpRequestBuilder.Post("https://furion.net/")
.WithHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0", replace: true);
19.28.6 发送相对地址(内部)请求
在 ASP.NET 或 Blazor 等 Web 应用中,发送内部 HTTP 请求时,通常使用相对地址。然而,由于项目启动前无法获取主机地址和端口,无法直接通过 services.AddHttpClient() 配置 BaseAddress。此时,可以通过配置 HttpRemoteOptions 的 FallbackBaseAddress 来实现。
ASP.NET应用
services.AddHttpRemote()
.ConfigureOptions((options, serviceProvider) =>
{
var serverAddressesFeature = serviceProvider.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>()!;
options.FallbackBaseAddress = new Uri(serverAddressesFeature.Addresses.FirstOrDefault());
});
由于 BackgroundService 是后台服务,默认不在 Web 线程中运行。如果在其派生类中发送相对地址(内部)的 HTTP 请求,可能会出现 serverAddressesFeature.Addresses 为空的情况。这是因为 BackgroundService 派生类的启动时机在 Web 主机启动之前,此时 Web 主机地址和端口还未分配。
如果出现这种情况,可以通过 IConfiguration 配置读取 Urls 节点来设置 FallbackBaseAddress 地址。
Blazor WebAssembly应用
services.AddHttpRemote()
.ConfigureOptions((options, serviceProvider) =>
{
var navigation = serviceProvider.GetRequiredService<NavigationManager>();
options.FallbackBaseAddress = new Uri(navigation.BaseUri);
});
通过上述配置,可以发送相对地址(内部)请求,示例如下:
var content = await httpRemoteService.GetAsStringAsync("/user/1"); // 相对地址(内部)
在发送相对地址请求时,系统会自动获取 Web 主机启动时的主机地址和端口进行拼接。例如,最终发送的请求地址可能为:https://localhost:5001/user/1。这种方式简化了内部请求的配置,确保在项目启动时动态获取主机地址和端口,从而避免硬编码带来的维护问题。
19.28.7 获取响应 Cookie
在 HTTP 请求中,如果服务器设置了 Cookie,响应头中会包含一个或多个 Set-Cookie 键值对。客户端接收到响应后,可以通过读取这些 Set-Cookie 键值对来获取 Cookie 信息。框架提供了以下两种便捷的方式来获取 Cookie:
1. 使用 HttpRemoteResult<TResult> 返回值类型
HttpRemoteResult<TResult> 是一个泛型类型,专门用于封装 HTTP 远程请求模块中的响应内容。该类型不仅包含了常用的 HTTP 响应信息,还提供了请求耗时等功能。
// 使用请求谓词方式(result 类型为 HttpRemoteResult<string>)
var result = await httpRemoteService.GetAsync<string>("https://furion.net/");
var setCookies = result.SetCookies; // 获取响应中的 Cookie 集合(IList<SetCookieHeaderValue> 类型)
var rawSetCookies = result.RawSetCookies; // 获取原始响应头中的 Set-Cookie 集合(List<string> 类型)
// 使用构建器方式同样适用(result 类型为 HttpRemoteResult<string>)
var result = await httpRemoteService.SendAsync<string>(HttpRequestBuilder.Get("https://furion.net/"));
2. 使用 HttpResponseMessage 的 TryGetSetCookies 扩展方法
框架还为 HttpResponseMessage 和 HttpResponseHeaders 类型提供了 TryGetSetCookies 扩展方法,可以方便地读取并解析 Set-Cookie 响应头信息。
var httpResponseMessage = await httpRemoteService.GetAsync("https://furion.net/");
httpResponseMessage.TryGetSetCookies(out var setCookies, out var rawSetCookies);
// 或者通过 Headers 属性获取
// httpResponseMessage.Headers.TryGetSetCookies(out var setCookies, out var rawSetCookies);
通过以上两种方式,开发者可以轻松获取并处理 HTTP 响应中的 Cookie 信息。
19.28.8 配置 Windows 身份验证
Windows 身份验证是微软提供的一种安全机制,用于验证用户或实体的身份,确保他们对系统、网络资源和应用程序的访问符合安全策略。该机制通常用于 Windows 操作系统,允许用户无需手动输入用户名和密码即可登录系统或依赖该机制的应用程序。
在某些传统的基于 Windows 服务器部署的 Web 应用系统中,发送 HTTP 远程请求可能需要启用 Windows 身份验证。以下是两种常见的配置方式:
1. 使用当前 Windows 系统登录的用户(推荐)
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler // 或使用 SocketsHttpHandler
{
UseDefaultCredentials = true
});
// 配置特定客户端
services.AddHttpClient("furion")
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler // 或使用 SocketsHttpHandler
{
UseDefaultCredentials = true
});
2. 手动输入 Windows 系统用户名和密码
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler // 或使用 SocketsHttpHandler
{
Credentials = new NetworkCredential("windows登录用户名", "windows登录密码"),
PreAuthenticate = true
});
// 配置特定客户端
services.AddHttpClient("furion")
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler // 或使用 SocketsHttpHandler
{
Credentials = new NetworkCredential("windows登录用户名", "windows登录密码"),
PreAuthenticate = true
});
通过以上配置,您可以根据需求选择使用当前系统用户或手动输入凭据来启用 Windows 身份验证。
19.28.9 配置 Kerberos 和 Active Directory 身份验证
Kerberos 是一种网络认证协议,它利用对称密钥加密技术来验证用户和服务的身份。通过使用票证(tickets)机制,Kerberos 能够确保在网络上的通信是安全的,并且可以有效地防止窃听、重放攻击等安全威胁。自 Windows 2000 开始,Kerberos 成为了域环境下的默认认证协议。
Active Directory (AD) 是微软提供的一系列目录管理服务,用于 Windows 域网络的管理和安全设置。它允许 IT 管理员管理网络中的用户、设备和其他资源,并提供了诸如身份验证、授权等功能。AD 支持多种认证协议,包括 NTLM(NT LAN Manager),但更推荐使用 Kerberos 因为其更高的安全性。
如果您的应用程序运行在域环境中,并且目标服务支持 Windows 身份验证(如 Negotiate 或 NTLM),可以直接使用 Windows 身份验证的配置方法。以下是具体配置示例:
1. 使用当前域用户的凭据(推荐)
此方式适用于应用程序与目标服务在同一个域环境中运行的情况。系统会自动使用当前域用户的凭据进行身份验证。
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler // 或使用 SocketsHttpHandler
{
UseDefaultCredentials = true
});
// 配置特定客户端
services.AddHttpClient("furion")
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler // 或使用 SocketsHttpHandler
{
UseDefaultCredentials = true
});
2. 跨域环境的 Kerberos 身份验证
如果应用程序与目标服务不在同一个域环境中,可以通过安装 Microsoft.Identity.Client 库来实现跨域身份验证。该库提供了对 Kerberos 和其他身份验证协议的支持。
安装 NuGet 包
dotnet add package Microsoft.Identity.Client
使用 Microsoft.Identity.Client 实现身份验证
以下是一个简单的示例,展示如何使用 Microsoft.Identity.Client 获取访问令牌并进行身份验证:
using Microsoft.Identity.Client;
// 配置身份验证参数
var clientId = "你的客户端ID";
var tenantId = "你的租户ID";
var authority = $"https://login.microsoftonline.com/{tenantId}";
var app = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(authority)
.Build();
// 获取访问令牌
var scopes = new[] { "api://目标服务的作用域" };
var result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
// 使用访问令牌调用目标服务
httpRemoteService.SendAsync(HttpRequestBuilder.Post("https://furion.net/")
.AddJwtBearerAuthentication(result.AccessToken));
3. 参考文档
- Microsoft.Identity.Client NuGet 包
- 适用于.NET 的 Microsoft 身份验证库 (MSAL) 文档
- How to authenticate with Kerberos using.NET
通过以上配置,您可以根据应用程序的运行环境选择合适的身份验证方式,确保安全访问目标服务。
19.28.10 响应内容解压(支持 gzip、deflate 和 brotli)和内容乱码处理
在现代主流的 Web 框架中,多数已内置支持服务器响应内容的压缩机制,其中最常用的压缩方式包括 gzip、deflate 和 brotli。在发起 HTTP 请求时,若服务器返回的响应内容启用了压缩,默认情况下,框架默认会自动解压这些内容(针对 gzip、deflate 和 brotli 格式)。
若需启用自定义解压功能,可通过配置客户端行为实现。具体方法如下:
配置自动解压
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.All, // 启用 gzip、deflate 和 brotli 自动解压
// AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate // 仅启用 gzip 和 deflate 自动解压
});
通过上述配置,若将 AutomaticDecompression 设置为 DecompressionMethods.All,则框架会自动处理 gzip、deflate 和 brotli 压缩格式的响应内容;若仅设置为 DecompressionMethods.GZip | DecompressionMethods.Deflate,则只会自动解压使用 gzip 和 deflate 压缩的内容。
需要注意的是:当响应头中的 Content-Encoding 包含上述压缩方式时,框架才会尝试自动解压。因此,在未包含 brotli 的配置中,相关响应内容将不会被自动解压。
手动处理解压(如自动解压失效或处理非标准编码)
当需要手动处理解压时,可按以下步骤操作:
- 关闭自动解压
// 配置默认客户端,关闭所有自动解压
services.AddHttpClient(string.Empty)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.None // 禁用自动解压
});
- 检查响应头的
Content-Encoding
var response = await httpRemoteService.GetAsync("https://furion.com");
if (response.Content.Headers.ContentEncoding.Contains("gzip"))
{
// 检测到 gzip 编码,可进行手动解压
}
- 执行手动解压(以
gzip为例)
using var responseStream = await response.Content.ReadAsStreamAsync();
using var gzipStream = new GZipStream(responseStream, CompressionMode.Decompress);
using var reader = new StreamReader(gzipStream);
var content = await reader.ReadToEndAsync();
Console.WriteLine(content);
19.28.11 JSON 序列化配置
框架默认采用 System.Text.Json 处理 HTTP 请求的 JSON 序列化,支持以下配置方式:
- 全局默认配置
通过 HttpRemoteOptions 为所有 HttpClient 设置统一的 JSON 序列化行为:
services.AddHttpRemote(builder => {})
.ConfigureOptions(options => // 或使用重载:.ConfigureOptions((options, serviceProvider) =>
{
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
- 客户端级配置(优先级更高)
当同时存在全局配置和客户端级配置时,框架会优先采用客户端级配置:
// 配置默认客户端
services.AddHttpClient(string.Empty)
.ConfigureOptions(options => // 或使用重载:.ConfigureOptions((options, serviceProvider) =>
{
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
// 配置特定客户端
services.AddHttpClient("furion")
.ConfigureOptions(options => // 或使用重载:.ConfigureOptions((options, serviceProvider) =>
{
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
使用示例:
var model = await httpRemoteService.SendAsAsync<YourModel>(HttpRequestBuilder.Get("https://furion.net/test-json")
.SetHttpClientName("furion")); // 不设置默认为 string.Empty
- 手动处理(完全控制)
当需要特殊处理时可直接操作原始响应:
var jsonString = await httpRemoteService.GetAsStringAsync("https://furion.net/test-json");
var model = JsonSerializer.Deserialize<YourModel>(jsonString, new JsonSerializerOptions());
如果您希望替换框架默认的 System.Text.Json 序列化提供程序,例如使用 Newtonsoft.Json 来提供 JSON 序列化配置选项,那么您可以通过实现 IHttpContentProcessor 接口来满足这一自定义需求。
但请注意,除非有充分的理由,否则通常建议使用 System.Text.Json,因为它与 .NET Core 紧密集成,且性能优异。
19.28.12 禁用分布式跟踪上下文(traceparent 标头)
在发起 HTTP 远程请求时,默认情况下,当前的 Activity 所包含的分布式跟踪上下文(如 traceparent 和 tracestate)会被自动注入到请求的 HTTP 标头中。这一机制有助于下游服务正确识别并关联到同一分布式跟踪链路。
如果出于某些业务或安全需求,需要禁用该自动注入行为,可以通过以下代码进行配置:
// 配置默认客户端
services.AddHttpClient(string.Empty, client => { })
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler()
{
ActivityHeadersPropagator = null // 禁用分布式上下文传播,或使用 DistributedContextPropagator.CreateNoOutputPropagator()
});
通过将 ActivityHeadersPropagator 设置为 null,可阻止运行时自动将当前活动的分布式跟踪信息注入到 HTTP 请求头中,从而实现对跟踪上下文传播的控制。相关 Issue 了解:#109558,#90407,#IC7ZZS。
19.28.13 设置 Content-Type(MIME)
在发送 HTTP 远程请求时,如果请求中包含数据体,通常需要正确设置 Content-Type 请求头,以指明发送内容的 MIME 类型,例如 application/json 或 application/x-www-form-urlencoded。
手动输入 MIME 类型容易拼写错误,从而引发潜在问题。为避免此类错误,推荐使用框架提供的 MediaTypeNames 静态类,该类封装了常用的标准 MIME 类型常量,能够有效提升代码的可读性和健壮性。
以下是使用 MediaTypeNames 设置 Content-Type 的示例代码:
HttpRequestBuilder.Get("https://furion.net/")
.SetContentType(MediaTypeNames.Text.Plain); // text/plain
HttpRequestBuilder.Post("https://furion.net/")
.SetContentType(MediaTypeNames.Application.Json); // application/json
HttpRequestBuilder.Post("https://furion.net/")
.SetContentType(MediaTypeNames.Application.FormUrlEncoded); // application/x-www-form-urlencoded
通过上述方式设置 Content-Type,不仅避免了手动输入错误,还能提升开发效率与代码可维护性。
19.28.14 在非依赖注入环境中使用(Console/WinForms/WPF)
在 ASP.NET Core 或 Worker Service 等应用程序中,通常内置了依赖注入支持。你只需在 Startup.cs 或 Program.cs 文件中,通过 services 或 builder.Services 注册所需服务即可。
但在某些特定场景下,例如控制台应用(Console)、WinForms 或 WPF 项目中,.NET 并未默认集成完整的依赖注入容器。针对这些场景,您可以使用 HttpRemoteClient 静态类的 Service 属性来发起远程 HTTP 请求:
var result = await HttpRemoteClient.Service.GetAsStringAsync("https://furion.net/");
自定义配置 HTTP 远程请求服务
如果需要自定义配置 HTTP 远程请求服务,可以通过调用 HttpRemoteClient.Configure(services => {}) 方法进行设置:
HttpRemoteClient.Configure(services =>
{
// 示例:配置默认的 HttpClient
services.AddHttpClient(string.Empty).AddProfilerDelegatingHandler();
// 如需自定义 HTTP 远程请求服务,可通过调用 AddHttpRemote() 进行配置;默认情况下无需注册
// services.AddHttpRemote();
});
完成自定义配置后,HttpRemoteClient.Service 静态属性将自动使用最新的服务构建信息实例。
请注意,HttpRemoteClient.Service 实例与在依赖注入环境下的 IHttpRemoteService 实例是不同的实例。
前者内部维护了一个独立的 IServiceProvider 实例,而后者则是基于应用程序主机的根服务提供程序解析而来。
因此,建议在应用程序关闭或不再需要使用 HTTP 远程请求服务时,手动调用 HttpRemoteClient.Dispose() 方法以释放资源:
HttpRemoteClient.Dispose();
请注意:一旦调用了 Dispose() 方法,HttpRemoteClient.Service 将无法再次实例化。
除了使用 HttpRemoteClient 静态类提供的 Service 属性外,您还可以选择手动构建服务容器并从中解析 IHttpRemoteService 实例,示例如下:
// 创建一个新的 ServiceCollection 实例
var services = new ServiceCollection();
// 向 ServiceCollection 中添加所需的 HTTP 远程请求服务
services.AddHttpRemote();
// 构建 ServiceProvider 实例
using var provider = services.BuildServiceProvider();
// 从 ServiceProvider 中获取 IHttpRemoteService 实例
var httpRemoteService = provider.GetRequiredService<IHttpRemoteService>();
这种方式适用于需要完全控制依赖注入容器生命周期的场景。
19.28.15 与旧版 Java 程序提供的 API 对接
在与旧版 Java 程序提供的 API 接口进行对接时,通常需要启用自动设置 Host 标头的功能,以确保请求能够正常发送。例如:
HttpRequestBuilder.Get("https://furion.net")
.AutoSetHostHeader(); // 启用自动设置 Host 标头
19.28.16 AddHttpRemote 二义性错误
若遇到 AddHttpRemote 方法的二义性错误,可通过为其添加一个空的委托参数来解决,示例如下:
services.AddHttpRemote(builder => {});
19.29 反馈与建议
给 Furion 提 Issue。
如需深入了解 HTTP 和 HttpClient 的相关知识,可参考以下文档章节: