现有项目具有从以下任一项继承的控制器:
-
Controller
:RouteTable.Routes.MapRoute
与"{controller}/{action}/{id}"
. -
ApiController
:GlobalConfiguration.Configure
并在回调MapRoute
中使用"api/{controller}/{id}"
.
一切正常,但我需要在这两种类型的控制器中生成动作方法的URL . 鉴于:
-
从其中任何一个继承的控制器的名称或类型,和
-
一个动作方法名称
然后从网站方面,我如何为Web API方面生成正确的URL?
我正在使用反射来获取动作和控制器名称,然后通过使用 UrlHelper.Action(actionName, controllerName, routeValueDictionary)
获取网站路由的正确URL .
但是,这种方法(当然)为WebAPI端生成这样的URL: /ApiControllerName/Get?parameter1=value
,当它需要 /api/ApiControllerName?parameter1=value
时,以及它是GET请求的单独知识 .
目的:这是针对网站的烟雾测试页面,该页面使用属性和反射来决定吸烟测试的内容 . 能够在整个项目中使用相同的属性会很好,而且能够使用正确的 UrlHelper
并且能够产生正确的前缀(例如 /api/
,而不是该代码可能错误地假设API路由已使用 api
注册,而不是 webapi
.
Update
在继续研究后,我发现the Url.HttpRouteUrl method可以生成WebAPI URL,但这需要知道路由名称,而不是操作方法名称 .
我更接近解决方案了 . 看起来如果您知道相应路线的路线名称you can cook up a Url easily . 还有一些可能的提示here和here . 但是,如果有多个WebApi路由,您如何知道哪个路由与您想要的控制器和操作相匹配?重新实现MVC本身在选择控制器和动作方面已经做的事情将是愚蠢的 . 我想我可以使用每个WebApi路由从给定参数构造一个URL,然后通过它的步调运行URL(使用上面的一些链接)并查看它是否与所需的控制器匹配... yuck .
必须有一个更简单的方法 .
现在我将不得不继续前进,但是希望有人可以帮助我 .
3 回答
这里有几种方法可以做到:
RouteUrl()
方法:诀窍当然是
httproute = true
. 设置此属性,通知您只需要http路由(Web Api路由) .HttpRouteUrl()
方法:httproute
值:这三种方式基本相同 . 由于您未指定路线,系统将根据路线值尝试查找第一个匹配项 . 例如,假设您有一个名为
RestfulController
的ApiController
,并且Web api路由配置如下:使用第一种方法,当您在MVC
Controller
中执行var url = Url.RouteUrl(new { id = 123, controller = "restful", httproute = true });
时,url
中的值为/api/restful/123
.但是如果你添加一个新路由ConstraintApi:
RouteUrl
返回的网址是/api2/restful/123
.在宣布路线时,您应该知道订单 . 如果在路径
ConstraintApi
之前添加了路径DefaultApi
,则生成的URL为/api/restful/123
.有Hyprlinkr库,允许您使用路径配置从Controller和Action创建URI .
这似乎更像是一个黑客,但如果你只打算用它进行测试,那值得一试 . 如您所述,您可以生成带有路由名称的URL . 因此,您可以获取所有路径名称并生成所有可能的URL . 然后,您需要检查URL是否解析为您需要的操作 . 为此,您可以使用以下内容:https://stackoverflow.com/a/19382567/1410281 . 基本的想法是,如果你有一个URL,那么在那里做一个假的重定向,并从框架中获取路由数据 .