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