.NET 7中HTTP Client调用触发FormatException:值格式无效
.NET 7集成测试HTTP调用全部失败:System.FormatException错误
升级到.NET 7后,所有集成测试中的HTTP调用均失败,抛出如下错误:
Message: System.FormatException : The format of value '' is invalid. Stack Trace: HttpHeaderParser.ParseValue(String value, Object storeValue, Int32& index) HttpHeaders.ParseAndAddValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info, String value) HttpHeaders.Add(HeaderDescriptor descriptor, String value) CookieContainerHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
这些测试在.NET 5和.NET 6中可正常运行。
示例测试代码
public async Task ShouldGetStatusOfRunFromAPI() { var client = CreateClient(this.mockApiServer.Uri.ToString()); HttpResponseMessage response = await client.GetAsync(StatusAPIForAuroraRun1ContextPath); Assert.Equal(HttpStatusCode.OK, response.StatusCode); }
CreateClient方法实现
protected HttpClient CreateClient(string uri) { var projectDir = Directory.GetCurrentDirectory(); var factory = new WebApplicationFactory<Program>(); var config = TestConfigurationHelper.LoadConfiguration(); return factory .WithWebHostBuilder(builder => { builder.ConfigureTestServices(services => { services.Configure<ClassOptions>(options => config.GetSection(ClassOptions.Name).Bind(options)); SomeService someService = NewService(config); services.AddSingleton(someService); Kubernetes kubernetesClient = NewKubernetesClient(uri); services.AddSingleton<IKubernetes, Kubernetes>((svcProvider) => kubernetesClient); services.AddSingleton<ISecretProvider, SecretProvider>((svcProvider) => NewSecretProvider()); }) .ConfigureAppConfiguration((context, builder) => { builder.AddConfiguration(config); }); }) .CreateClient(); }
排查过程
错误指向请求头格式无效,但未明确具体是哪个头。已尝试显式设置Accept头:
client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
但问题依旧。调用GetAsync()时的请求头显示存在空值的Cookie项。
解决方案
1. 禁用自动Cookie处理
从错误栈可看出问题出在CookieContainerHandler,.NET 7对HTTP头格式校验更严格,空字符串的Cookie值不再被允许。可在创建HttpClient时禁用Cookie自动处理:
return factory .WithWebHostBuilder(builder => { // 原有配置代码 }) .CreateClient(new WebApplicationFactoryClientOptions { Handler = new HttpClientHandler { UseCookies = false } });
2. 排查Cookie来源
检查测试代码或依赖服务(比如Kubernetes客户端)是否自动添加了空值Cookie:
- 查看
NewKubernetesClient方法,确认创建客户端时是否注入了空的Cookie头 - 检查测试配置文件,确认是否存在导致空Cookie的配置项
3. 清理空Cookie
如果需要保留Cookie处理逻辑,可在发送请求前手动清理空值Cookie:
var client = CreateClient(this.mockApiServer.Uri.ToString()); // 清理空值Cookie foreach (var cookieHeader in client.DefaultRequestHeaders.GetValues("Cookie").ToList()) { var cleanedCookies = cookieHeader.Split(';') .Where(c => !string.IsNullOrWhiteSpace(c.Split('=').LastOrDefault())) .Join(";"); client.DefaultRequestHeaders.Remove("Cookie"); if (!string.IsNullOrWhiteSpace(cleanedCookies)) { client.DefaultRequestHeaders.Add("Cookie", cleanedCookies); } }
内容的提问来源于stack exchange,提问作者Kruti Joshi
相关产品推荐
相关产品推荐

