【问题标题】:Three routes for one verb in Web APIWeb API 中一个动词的三个路由
【发布时间】:2013-10-15 02:26:33
【问题描述】:

我正在尝试使以下三种途径起作用:

  • GET /api/category - 列出所有类别
  • GET /api/category/1 - 获取有关第 1 类的详细信息
  • GET /api/category/1/questions - 获取类别 1 的问题

我无法让此路由正常工作。

我的CategoryController有以下三个方法定义:

public IEnumerable<Category> Get() {}
public Category Get(int id) {}
public IEnumerable<QuestionSummary> GetQuestions(int id) {}

我怎样才能让这些匹配而不相互冲突?我们已经在项目的其他部分使用了 AttributeRouting。

【问题讨论】:

    标签: c# asp.net-web-api asp.net-mvc-routing asp.net-web-api-routing


    【解决方案1】:

    以下应该有效:

    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "SubResource",
            routeTemplate: "api/{controller}/{categoryId}/{action}"
        );
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
    

    和你的控制器:

    public class CategoryController : ApiController
    {
        public IEnumerable<Category> Get() 
        {
            ...
        }
    
        public Category Get(int id) 
        {
            ...
        }
    
        [HttpGet]
        public IEnumerable<QuestionSummary> Questions(int categoryId) 
        {
            ...
        }
    }
    

    ASP.NET Web API 2 使这个场景更容易,因为它允许attribute based routing

    我相信微软最终会做对(就像ServiceStack 做的那样)。希望在 ASP.NET Web API 3 中,他们将引入基于消息的路由,并且他们将以正确的方式构建 REST 框架——它将是基于消息的,并且将对这些消息进行路由。

    【讨论】:

    • 您在技术上是正确的,但是直到我在不同的路由中为 id 字段使用不同的名称之前,我无法让它工作。非常不直观,但是,嘿,它有效! :)
    【解决方案2】:

    我认为你不能在同一个控制器上对同一个动词有多个方法,除非你使用“action”。

    我猜你可以使用 3 个不同的控制器来处理你的 3 个路由,只要你按照正确的顺序注册它们。

    config.Routes.MapHttpRoute(
        name: "Route1",
        routeTemplate: "/api/category/{id}/questions",
        controllerType: typeof(YourController1)
        );
    
    config.Routes.MapHttpRoute(
        name: "Route2",
        routeTemplate: "/api/category/{id}",
        controllerType: typeof(YourController2)
        );  
    
    config.Routes.MapHttpRoute(
        name: "Route3",
        routeTemplate: "/api/category",
        controllerType: typeof(YourController3)
        );
    

    【讨论】:

    • 在这种情况下你会如何使用“action”?使用上述定义时,如何禁用此控制器的现有路由?
    • 使用动作你必须修改路由模板。例如:/api/category -> /api/category/list 其中 list 是操作。我知道如果您已经交付了您的 api,这是不可行的;我刚刚提到了在同一个控制器上为同一个动词处理多个方法的选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 2014-02-04
    相关资源
    最近更新 更多