You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:35:22