在我的Web API场景中,此(默认)路由适用于几乎所有控制器。
config.Routes.MapHttpRoute(
name: "DefaultRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
对于我的几个控制器,我想让它们按照动作名称进行映射,如下所示:
config.Routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
背景
默认情况下,我的大多数控制器都会映射到GEE,POST,PUT和DELETE。 但是,我保留了一些执行操作的“admin”控制器,例如数据初始化,清理和测试。这些控制器可能有多种方法,通过GET超越,因此是第二条路径。
如果我使用这些路线中的任何一个,它们运作良好,但是,如果我同时设置两个,我会遇到两个失败之一:
首先是默认路线:
api/books/ -> OK
api/books/someGuidId -> OK
api/admin/someAdminAction -> 500 Internal Server Error (multiple actions found)
api/test/sometestAction -> 500 Internal Server Error (multiple actions found)
行动路线首先:
api/books/ -> OK
api/books/someGuidId -> 404 Not Found (no action that matches "someGuidId")
api/admin/someAdminAction -> OK
api/test/sometestAction -> OK
我的问题是:如何让这些路线同时运作?
[修改
api / books / someGuidId不是一个重要的电话,我可以没有它(通过GET)但是,POST,PUT和DELETE到同一个url会失败,这是不可接受的。
答案 0 :(得分:3)
路径的顺序很重要,因此您应首先设置更具体的路径:
config.Routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
修改:
首先 Default
路线:
api/books/
此网址匹配第一个模式:api / {controller} / {id}。
Framework使用books
(PUT,POST,DELETE)方法查找GET
控制器,并找到它。使用默认id
值调用此方法。
api/admin/someAdminAction
此网址也匹配第一个模式。 (顺便说一句,在路由定义中如何命名您的参数并不重要:id
或superParamName
,当Framework将URL与路径进行比较时,它将仅查找模式,并且无法通过参数名称进行区分。
框架将尝试使用GET
id调用admin
控制器的someAdminAction
(PUT,POST,DELETE)方法(我认为,这不是有效的id值:)
您首先定义Action
路线时会得到类似的内容:
api/books/
匹配 api/{controller}/{id}
,id可以省略,因为它被设置为“可选”。
api/books/someGuidId
匹配 api/{controller}/{action}/{id}
,因此,当Framework在someGuidId
控制器中查找book
操作方法并且找不到它时,它会抛出异常。 404 Not Found(没有匹配“someGuidId”的操作)
编辑2:我认为,如果你总是将id
param传递给“动作”并首先放置“动作”路线,你就不会发生任何碰撞。试试这个。
如果您需要id
param在两种情况下都是可选的,您可以从两个路径中删除它并通过?
(问号)以正常方式传递它。
其中一个可以解决您的路由问题。