2

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

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

想法?注意:我更关心 WebAPI,而不是 100% REST。

示例 URL
// GET 小部件列表
http://somedomain.com/api/widget
// GET 特定小部件
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}"  
        );  
4

3 回答 3

5

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

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}"
    );
于 2012-08-23T15:04:22.850 回答
4

看看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进行轻微更改

(如果可能,请使用复数 widget*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" }
       );
    }
于 2012-08-23T15:10:39.983 回答
1

看看AttributeRouting;它应该能够轻松地做到这一点。

于 2012-08-23T21:20:03.900 回答