HttpClient GetAsync调用本地Web服务返回404问题排查
问题根因
这个404和控制器代码、URL拼写无关,是多端默认配置差异共同导致的:
- ASP.NET Core 6 用Kestrel或者IIS Express托管时,绑定
localhost域名默认只监听IPv4回环地址127.0.0.1的对应端口,不会绑定IPv6回环地址[::1]的同端口。 - Windows平台上,.NET Framework 4.8 解析
localhost时默认优先返回IPv6地址[::1],而Chrome、Edge等浏览器默认优先解析为IPv4地址127.0.0.1。 - 你本机IPv6回环地址的7065端口刚好被其他本地Web服务(之前启动未关闭的IIS Express实例、WSL映射端口、其他调试服务)占用,这个服务上不存在
/Api/GetStuff路径,因此返回404。
还有两个隐藏配置容易触发同类问题:
- .NET Framework 4.8 虽然支持TLS 1.2,但部分场景下不会默认启用,而.NET 6的Kestrel默认禁用TLS 1.0/1.1,即使连对地址也会出现握手失败。
- .NET Framework的HttpClient默认读取IE系统代理配置,部分代理工具对.NET程序的绕过规则不生效,会把本地接口请求转发到公网代理,代理找不到本地路径也会返回404。
修复方案
直接按以下代码修改控制台应用即可:
- 程序入口处显式开启TLS 1.2支持
- 请求地址把
localhost替换为127.0.0.1,强制走IPv4链路 - 初始化HttpClient时禁用本地代理,避免请求被错误转发
完整可运行代码:
using System.Net; using System.Net.Http; internal class Program { private HttpClient _client; static void Main() { // 显式启用TLS1.2,适配.NET6默认TLS配置 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; new Program().RunAsync().Wait(); } private async Task RunAsync() { // 禁用代理,强制使用IPv4地址请求 _client = new HttpClient(new HttpClientHandler { UseProxy = false }); var response = await _client.GetAsync("https://127.0.0.1:7065/Api/GetStuff"); // 调试代码,可打印响应结果验证 response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); Console.WriteLine($"接口返回结果:{result}"); } }
可选根治方案
如果不想每次本地调试都把localhost改成127.0.0.1,可以修改ASP.NET Core 6项目的配置,让Kestrel同时监听所有IP(包括IPv4和IPv6)的7065端口,在Program.cs中添加以下配置即可:
var builder = WebApplication.CreateBuilder(args); // 添加以下配置,让Kestrel监听所有网卡IP的7065端口 builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(7065, listenOpt => { listenOpt.UseHttps(); }); }); // 其余原有配置保持不变...
内容的提问来源于stack exchange,提问作者Oliver Schimmer
相关产品推荐
相关产品推荐

