ASP.NET MVC 4 - API路由 - 在URL中指定操作

时间:2012-08-23 13:50:51

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

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

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

思考?注意:我更关注WebAPI然后是100%REST。

示例网址
//获取小部件列表
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}"  
        );  

3 个答案:

答案 0 :(得分:5)

我会尝试将第二个模式(一个“动作”,一个字符串类型,后跟一个斜杠和一个int ID)放在比更高的优先级(传递一个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}"
    );

答案 1 :(得分:4)

查看http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api - 特别是“按行动名称路由”

部分

从中推荐了轻微的变化     http://somedomain.com/api/widget/promote/1 至     http://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" }
       );
    }

答案 2 :(得分:1)

看看AttributeRouting;它应该能够轻松实现这一目标。

相关问题