首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Web API路由- api/{controller}/{action}/{id}“故障”接口/{controller}/{id}

Web API路由- api/{controller}/{action}/{id}“故障”接口/{controller}/{id}
EN

Stack Overflow用户
提问于 2012-11-28 09:39:18
回答 5查看 120.1K关注 0票数 95

我在Global.asax中有默认路由:

代码语言:javascript
复制
 RouteTable.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

我希望能够针对特定的功能,所以我创建了另一个路由:

代码语言:javascript
复制
RouteTable.Routes.MapHttpRoute(
         name: "WithActionApi",
         routeTemplate: "api/{controller}/{action}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

因此,在我的控制器中,我有:

代码语言:javascript
复制
    public string Get(int id)
    {
        return "object of id id";
    }        

    [HttpGet]
    public IEnumerable<string> ByCategoryId(int id)
    {
        return new string[] { "byCategory1", "byCategory2" };
    }

.../api/records/bycategoryid/5打电话会给我我想要的。但是,调用.../api/records/1会给出错误

找到了与请求匹配的多个操作:...

我理解其中的原因--路由只是定义了哪些URL是有效的,但是当涉及到函数匹配时,Get(int id)ByCategoryId(int id)都会匹配api/{controller}/{id},这就是让框架感到困惑的地方。

我需要做什么才能让默认的API路由再次工作,并保留使用{action}的路由?我考虑创建一个名为RecordByCategoryIdController的不同控制器来匹配默认的API路由,为此我将请求.../api/recordbycategoryid/5。然而,我发现这是一个“脏”(因此不令人满意)的解决方案。我一直在寻找这个问题的答案,但没有任何关于在{action}中使用路由的教程提到了这个问题。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-11-28 10:15:43

路由引擎使用与您向其中添加规则时相同的顺序。一旦它获得了第一个匹配的规则,它将停止检查其他规则,并利用它来搜索控制器和操作。

因此,您应该:

  1. 将您的特定规则放在常规规则(如default)之前,这意味着使用RouteTable.Routes.MapHttpRoute首先映射"WithActionApi“,然后映射"DefaultApi”。
  2. 删除您的“defaults: new { id = System.Web.Http.RouteParameter.Optional }”规则的WithActionApi参数,因为一旦id是可选的,像"/api/{part1}/{part2}“这样的url将永远不会进入到您的"DefaultApi”的命名操作,以告知路由引擎进入哪个操作。否则,一旦您的控制器中有多个操作,引擎将不知道要使用哪个操作,并抛出“找到与请求匹配的多个操作:...”。然后,要使其与Get方法匹配,请使用ActionNameAttribute.

因此,您的路由应该如下所示:

代码语言:javascript
复制
// Map this rule first
RouteTable.Routes.MapRoute(
     "WithActionApi",
     "api/{controller}/{action}/{id}"
 );

RouteTable.Routes.MapRoute(
    "DefaultApi",
    "api/{controller}/{id}",
    new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional }
);

和你的控制器:

代码语言:javascript
复制
[ActionName("DefaultAction")] //Map Action and you can name your method with any text
public string Get(int id)
{
    return "object of id id";
}        

[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
    return new string[] { "byCategory1", "byCategory2" };
}
票数 105
EN

Stack Overflow用户

发布于 2014-06-18 15:56:54

您可以使用Attribute routing解决您的问题

控制器

代码语言:javascript
复制
[Route("api/category/{categoryId}")]
public IEnumerable<Order> GetCategoryId(int categoryId) { ... }

jquery中的URI

代码语言:javascript
复制
api/category/1

路由配置

代码语言:javascript
复制
using System.Web.Http;

namespace WebApplication
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();

            // Other Web API configuration not shown.
        }
    }
}

并且您的默认路由是作为基于默认约定的路由工作的

控制器

代码语言:javascript
复制
public string Get(int id)
    {
        return "object of id id";
    }   

Jquery中的URI

代码语言:javascript
复制
/api/records/1 

路由配置

代码语言:javascript
复制
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

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

有关Attribute routing and onvention-based routing herethis的详细信息,请查看文章

票数 40
EN

Stack Overflow用户

发布于 2018-09-10 15:53:31

尝尝这个。

代码语言:javascript
复制
public class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        var json = config.Formatters.JsonFormatter;
        json.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
        config.Formatters.Remove(config.Formatters.XmlFormatter);

        // Web API routes
        config.MapHttpAttributeRoutes();

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

        );
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13596391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档