【问题标题】:ASP.NET MVC 4 - API Routing - Specifying Action in the URLASP.NET MVC 4 - API 路由 - 在 URL 中指定操作
【发布时间】:2012-08-24 05:20:03
【问题描述】:

我有一个用 ASP.NET MVC 4 框架编写的 Web 服务。它的基本 CRUD 操作可以很好地映射到 REST 动词,但我需要添加一个没有的操作。

什么是正确的方法来指定有时在 URL 末尾传递一个 ID 的能力,你知道这将是一个整数类型,有时它是一个“动作”一个字符串类型,后跟一个斜杠和一个 int ID?需要有关正确路由器映射的帮助。

想法?注意:比起 100% REST,我更关心 WebAPI。

示例网址
// 获取小部件列表
http://somedomain.com/api/widget
// 获取特定的小部件
http://somedomain.com/api/widget/1
// POST - 对特定小部件执行特殊操作 - 提升
http://somedomain.com/api/widget/promote/1

这是处理它的正确方法吗?

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

        routes.MapHttpRoute(  
            name: "DefaultApiExtended",  
            routeTemplate: "api/{controller}/{action}/{id}"  
        );  

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    我会尝试将第二个模式 (一个“动作”一个字符串类型,后跟一个斜杠和一个 int ID) 放在比 更高的优先级(在您知道的 URL 的末尾将是整数类型)

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

    您的操作和您的 ID 并非您所期望的那样可选。如果没有匹配,DefaultApi 规则应该接管处理。

    编辑:

    只是想,如果您确实希望它是“RESTy”,那么您可以随时切换 ID,因此对于此小部件,使用此 ID,执行此操作。

    routes.MapHttpRoute(
            name: "ActionWithId",
            routeTemplate: "api/widget/{id}/{action}"
        );
    

    【讨论】:

      【解决方案2】:

      看看http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api - 特别是“按操作名称路由”部分

      建议稍作改动 http://somedomain.com/api/widget/promote/1http://somedomain.com/api/widgets/1/promote

      (如果可能,请使用复数小部件*s*)

      您的控制器需要如下所示:

      public class WidgetsController : ApiController
      {
          [HttpPost]
          /// POST api/widgets/1/promote
          public void Promote(int id)
          {
      
          }
      
          // GET api/widgets/1
          public string Get(int id)
          {
              return "value";
          }
      
      }
      

      还有路线:

      public static void RegisterRoutes(RouteCollection routes)
          {
              routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      
              routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "api/{controller}/{id}",
                  defaults: new { id = RouteParameter.Optional }
              );
      
              routes.MapHttpRoute(
                 name: "DefaultPromoteActionApi",
                 routeTemplate: "api/{controller}/{id}/{action}",
                 defaults: new { action = "Promote" }
             );
          }
      

      【讨论】:

      • +1 - 轻微变化 - 您将如何处理像 dequeue 这样的事情,您确实想指定操作但没有 ID?谢谢。
      • @brun 抱歉,我不完全理解...比如 api/widgets/promote 吗?
      【解决方案3】:

      看看AttributeRouting;它应该能够轻松完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-03
        • 2017-09-23
        • 1970-01-01
        • 1970-01-01
        • 2013-02-14
        • 1970-01-01
        • 1970-01-01
        • 2012-09-28
        相关资源
        最近更新 更多