【问题标题】:Routing issue: Multiple actions were found that match the request路由问题:找到与请求匹配的多个操作
【发布时间】:2013-03-04 03:34:42
【问题描述】:

我的路线:

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: null,
                constraints: new { id = @"^\d+$" }
            );

            routes.MapHttpRoute(
                name: "ApiControllerActionRoute",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );

我的方法:

// GET api/Set/All
        [ActionName("All")]
        public IEnumerable<Set> GetSets()
        {
            var sets = _repository.GetAllSets();
            return sets;
        }

        // GET api/Set/TopLevelSets
        [ActionName("TopLevelSets")]
        public IEnumerable<Set> GetTopLevelSets()
        {
            var sets = _repository.GetTopLevelSets();
            return sets.ToList();
        }

        // GET api/Set/Breadcrumbs/1
        [ActionName("Breadcrumbs")]
        public IEnumerable<Set> GetBreadCrumbs(int id)
        {
            var sets = _repository.GetBreadcrumbs(id);
            return sets.ToList();
        }

        // GET api/Set/5
        public Set GetSet(int id)
        {
            Set set = _repository.GetSet(id);
            if (set == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }

            return set;
        }

        // PUT api/Set/5
        public HttpResponseMessage PutSet(Set set)
        {
            if (!ModelState.IsValid)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }

            _repository.UpdateSet(set);

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        // POST api/Set
        public HttpResponseMessage PostSet(Set set)
        {
            if (ModelState.IsValid)
            {
                _repository.AddSet(set);
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, set);
                return response;
            }
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }

        // DELETE api/Set/5
        public HttpResponseMessage DeleteSet(int id)
        {         
            _repository.DeleteSet(id);
            return Request.CreateResponse(HttpStatusCode.OK, id);
        }

此时我正在尝试使用 localhost/api/set/1 - getSet 方法。一切似乎都与路线一致,但由于某种原因它不起作用。我错过了什么?

【问题讨论】:

  • 这是伪代码,还是剪切粘贴?您的 GetSet Action 缺少 ActionName 注释:[ActionName("Set")],因此 GetSet 与您正在寻找的 Set 路线不匹配
  • 剪切和粘贴 - 这不会打第一条路线并说控制器 = Set 和 id = 1?在我添加非标准方法和第二条路线注册之前,这是可行的。如果我添加 Action 注释,那么我不需要点击 /api/set/set/1 吗?
  • 否 - 操作名称属性实际上会将名称 GetSet 替换为您想要的名称“Set”。通过使用 [ActionName("Set")] 它将具有路由 /api (controller)/set (action) /1 (id) - 匹配您的 GetSet Action。或者,您可以将您的操作从 GetSet 重命名为 Set(无论如何这可能更容易理解)
  • 很抱歉我没有包含这个 - 我的控制器被命名为“SetController”。我正在通过 /api/set/all 访问 All - 但 api/set/1 给了我这个错误。这有什么不同吗?

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 routes


【解决方案1】:

您的默认路由未设置默认操作,因此当您使用“获取”操作时,路由引擎无法确定您需要 GetTopLevelSets 还是 GetSet。添加默认值将解决此问题:

 routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { action = "GetSet" },
                constraints: new { id = @"^\d+$" }
            );

将其默认为您的控制器中的GetSet 操作,使用:api/set (controller)/1 (id) 路由。

【讨论】:

  • 非常感谢。我希望通过 api/set(控制器)访问的 Put 操作呢?还是 DeleteSet > api/set/id 用于 DELETE?
  • 它们应该仍然可以工作 - 你的问题是当你有“Get”操作时,路由引擎无法决定你想要 GetTopLevelSets 还是 GetSet。现在,它会在 Get 请求上默认为 GetSet(put/post/delete 仍将默认为它们自己的)。不过,您必须明确访问 GetTopLevelSets。
  • 知道了!谢谢马克的解释。
【解决方案2】:

您是否缺少查询的 api 部分? localhost/api/set/1

【讨论】:

  • 哎呀!那个位打错了。我确实在尝试 /api/set/1
猜你喜欢
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 2018-11-04
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
相关资源
最近更新 更多