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

C# HttpClient请求无效地址返回200 OK,原因是什么?

问题诊断与修复

你的代码存在几个关键问题,导致HTTP请求结果不符合预期:

1. HttpClient的BaseAddress使用错误

你把包含端点的完整URL直接赋值给HttpClient.BaseAddress,再调用GetAsync("")发起请求。这种用法会触发HttpClient异常的URI解析逻辑——部分服务器会将此类请求重定向到根路径(返回200 OK的首页内容),而非返回无效端点对应的404状态码。

正确逻辑应该是:将根域名设为BaseAddress,在GetAsync方法中传入具体的端点路径。

2. 测试用例的预期值错误

你给无效端点Users2的测试用例设置的预期状态码是"OK",但实际该端点应返回"NotFound"(对应HTTP 404),这和你实际期望的结果完全矛盾。

3. 异步方法的同步等待方式不当

使用Task.Run(...).Wait()等待异步方法完成,不仅会造成不必要的线程开销,还可能在部分场景下引发死锁。NUnit原生支持异步测试方法,直接使用async/await即可。

修正后的代码

namespace TestProject1
{
    // 修正测试用例的预期状态码,Users2对应NotFound
    [TestFixture("OK", "Users")]
    [TestFixture("NotFound", "Users2")]
    public class Tests
    {
        public string ExpectedCode { get; }
        public string Endpoint { get; }
        // 根地址单独提取,避免重复拼接
        private readonly string _baseUrl = "https://examplewebsite.net";

        // 统一使用带两个参数的构造函数,避免重载混淆
        public Tests(string expectedCode, string endpoint)
        {
            ExpectedCode = expectedCode;
            Endpoint = endpoint;
        }

        public async Task<string> HttpGetAsync(string baseUrl, string endpoint)
        {
            string fullUrl = $"{baseUrl}/{endpoint}";
            Console.WriteLine($"请求地址:{fullUrl}");
            string content = null;

            // 推荐复用HttpClient(可放在类级别,避免频繁创建实例耗尽Socket资源)
            using var client = new HttpClient
            {
                BaseAddress = new Uri(baseUrl)
            };

            // 传入端点路径发起请求
            var response = await client.GetAsync(endpoint);

            if (response.IsSuccessStatusCode)
            {
                content = await response.Content.ReadAsStringAsync();
            }
            Console.WriteLine($"响应内容:{content ?? "无内容"}");

            return response.StatusCode.ToString();
        }

        // 改为异步测试方法,使用await等待异步操作
        [Test]
        public async Task TestEndpointStatus()
        {
            string responseCode = await HttpGetAsync(_baseUrl, Endpoint);
            Assert.AreEqual(ExpectedCode, responseCode);
        }
    }
}

额外优化点

  • 复用HttpClient实例,而非每次请求都创建新实例,频繁创建会耗尽Socket资源,可将其声明为类的静态成员。
  • 使用字符串插值$"{baseUrl}/{endpoint}"替代string.Format,代码更简洁易读。
  • 给属性和方法起更清晰的命名(如ExpectedCode替代Code,TestEndpointStatus替代Test1),提升代码可维护性。

内容的提问来源于stack exchange,提问作者PanBocian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:40:04