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

React调用Web API触发System.InvalidOperationException错误排查

解决Web API调用GetSingle时的"Multiple actions were found"错误

问题背景

你有一个TestApiController,包含GetAllData和GetSingle两个GET方法,在React应用中调用GetSingle时遇到了多Action匹配的错误,尽管你添加了包含action参数的路由,但问题依然存在,且希望避免使用自定义路由属性。

相关代码

控制器代码(C#)

public IHttpActionResult GetAllData() { 
    var modelitems = new List<TestModel>(); 
    var items = AWEntity.GetProducts(); 
    var i = 0; 
    foreach (var item in items) { 
        var model = new TestModel { 
            Id = item.ProductId, 
            TestName = item.Name, 
            TestMessage = "My Message" + i, 
            ReorderPoint = item.ReorderPoint 
        }; 
        modelitems.Add(model); 
        i++; 
    } 
    return Ok(modelitems); 
} 

public IHttpActionResult GetSingle() { 
    var item = AWEntity.GetProduct(); 
    var model = new TestModel { 
        Id = item.ProductId, 
        TestName = item.Name, 
        TestMessage = "My Message" + 1, 
        ReorderPoint = item.ReorderPoint 
    }; 
    return Ok(model); 
}

React Fetch代码(JavaScript)

fetch('http://localhost:51620/api/TestApi/GetSingle')
 .then(result => result.json())
 .then(result => {
     this.setState({ items : result } )
 })

Web API路由配置(C#)

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
); 

config.Routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

错误信息

{ 
    "message": "An error has occurred.", 
    "exceptionMessage": "Multiple actions were found that match the request: \r\nGetData on type WebAPIComponent.Controllers.TestApiController\r\nGetSingle on type WebAPIComponent.Controllers.TestApiController", 
    "exceptionType": "System.InvalidOperationException", 
    "stackTrace": " at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()" 
}

错误原因

核心问题是路由注册顺序导致的匹配优先级问题:

  1. Web API的路由匹配是按照你注册的顺序来的,你先注册了DefaultApi路由(api/{controller}/{id}),它会优先匹配你的请求/api/TestApi/GetSingle——此时路由会把GetSingle解析为可选的id参数,而不是action名称。
  2. 当这个路由匹配成功后,Web API会去控制器中寻找符合GET请求的方法,但你的控制器里有两个以Get开头的方法(GetAllData和GetSingle),Web API无法确定应该调用哪一个,因此抛出了"Multiple actions were found"的错误。
  3. 你后来注册的带action参数的路由根本没有被匹配到,因为第一个路由已经先满足了匹配条件。

解决方案

调整路由的注册顺序,把包含action参数的API Default路由放在DefaultApi路由的前面:

// 先注册带action的路由,优先匹配
config.Routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

// 再注册默认路由,作为兜底
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

这样,当你请求/api/TestApi/GetSingle时,会优先匹配到带action参数的路由,Web API会根据action值找到对应的GetSingle方法,避免了多Action的歧义。

另外,虽然不是必须的,但为了让代码更清晰,建议给你的GET方法加上[HttpGet]属性(这不属于自定义路由属性,是HTTP动词属性),明确指定方法对应的HTTP请求类型,这样即使路由有变化,也能更准确地匹配:

[HttpGet]
public IHttpActionResult GetAllData() { ... }

[HttpGet]
public IHttpActionResult GetSingle() { ... }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:28:16