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

C# ApiController被HttpClient GetAsync调用两次问题求助

解决HttpClient GetAsync导致API接口被调用两次的问题

咱们先拆解下你遇到的这个奇怪问题,核心是同步阻塞异步代码+路由配置的小疏漏,共同导致了接口被执行两次的情况:

1. 同步阻塞异步方法是关键隐患

你的调用代码里混用了.Result和.Wait()这种同步阻塞方式,这在异步编程里是大忌,很容易触发意外的重复请求(比如上下文调度冲突、HttpClient隐性重试):

// 问题代码:同步阻塞异步操作
var response = _client.GetAsync("api/documents/GetAllDocuments").Result;
response.Content.LoadIntoBufferAsync().Wait();

正确的姿势是全程用async/await,保持异步流程的一致性,避免阻塞线程导致的异常:

public static async Task<Document> GetAllDocuments() 
{ 
    try 
    { 
        var response = await _client.GetAsync("api/documents/GetAllDocuments"); 
        await response.Content.LoadIntoBufferAsync();
        response.EnsureSuccessStatusCode(); 
        return await response.Content.ReadAsAsync<Document>(new[] { new JsonMediaTypeFormatter() }); 
    } 
    catch (Exception ex) 
    { 
        return null; 
    } 
}

2. 路由末尾的斜杠触发了重定向

你的WebApiConfig里第三个路由的末尾多了个斜杠:

config.Routes.MapHttpRoute( 
    "GetAllDocuments", 
    "api/documents/GetAllDocuments/"); // 末尾斜杠是坑!

当你请求api/documents/GetAllDocuments(不带斜杠)时,服务器会返回301重定向到带斜杠的地址,而HttpClient默认会自动跟随重定向,这就导致了两次调用接口。

解决方法很简单,移除路由末尾的斜杠,确保请求地址和路由规则完全匹配:

config.Routes.MapHttpRoute( 
    "GetAllDocuments", 
    "api/documents/GetAllDocuments");

3. 额外的小优化建议

  • 你的ApiController返回List<Document>,但调用方的返回类型是Task<Document>,类型不匹配可能会引发序列化异常,建议对齐两者的返回类型(要么接口返回单个Document,要么调用方返回Task<List<Document>>)。
  • _documentsRepository = DocumentsRepository.Instance;放在lock里没必要,单例的Instance本身应该是线程安全的,建议移到类初始化阶段完成。

按照上面的步骤修改后,应该就能彻底解决接口被重复调用的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:35:35