在包含Controllers和ApiControllers的项目中从ApiController和Action名称获取Url

Eri*_*ikE 10 c# asp.net-mvc asp.net-web-api

现有项目具有从以下任一项继承的控制器:

  • Controller:RouteTable.Routes.MapRoute"{controller}/{action}/{id}".
  • ApiController:GlobalConfiguration.Configure并在回调MapRoute"api/{controller}/{id}".

一切正常,但我需要在这两种类型的控制器中生成动作方法的URL.鉴于:

  1. 继承自其中任何一个的控制器的名称或类型,和
  2. 动作方法名称

然后从网站方面,我如何为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.

更新

在继续研究之后,我发现Url.HttpRouteUrl可以生成WebAPI URL 方法,但这需要知道路由名称,而不是操作方法名称.

我已经对此做了更多的研究,并且没有更接近解决方案.看起来如果您知道相应路线的路线名称,您可以轻松地制作一个URL.这里这里也有一些可能的提示.但是,如果有多个WebApi路由,您如何知道哪个路由与您想要的控制器和操作相匹配?重新实现MVC本身在选择控制器和动作方面已经做的事情将是愚蠢的.我想我可以使用每个WebApi路由从给定参数构造一个URL,然后通过它的步调运行URL(使用上面的一些链接)并查看它是否与所需的控制器匹配... yuck.

必须有一个更简单的方法.

现在我将不得不继续前进,但是希望有人可以帮助我.

Art*_*aca 5

这里有几种方法可以做到:

诀窍当然是httproute = true.设置此属性,通知您只需要http路由(Web Api路由).

  • 使用HttpRouteUrl()方法:

    var url2 = Url.HttpRouteUrl(null, new { id = 2, controller = ".." });
    
    Run Code Online (Sandbox Code Playgroud)
  • 另一种方法是直接使用路由和httproute值:

    var values = new RouteValueDictionary(new
    {
        id = 3,
        controller = "...",
        httproute = true
    });
    var url3 = RouteTable.Routes.GetVirtualPath(Request.RequestContext, values).VirtualPath;
    
    Run Code Online (Sandbox Code Playgroud)

这三种方式基本相同.由于您未指定路线,系统将根据路线值尝试查找第一个匹配项.例如,假设您有一个ApiController被调用的RestfulController和web api路由配置如下:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

使用第一种方法,当你var url = Url.RouteUrl(new { id = 123, controller = "restful", httproute = true });在一个MVC Controller中的价值url/api/restful/123.

但是如果你添加一个新路由ConstraintApi:

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 }
);
Run Code Online (Sandbox Code Playgroud)

返回的网址RouteUrl/api2/restful/123.

在宣布路线时,您应该知道订单.如果路由在路由DefaultApi之前添加ConstraintApi,则生成的URL为/api/restful/123.