Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在包含控制器和ApiController的项目中,从ApiController和操作名称获取Url_C#_Asp.net Mvc_Asp.net Web Api - Fatal编程技术网

C# 在包含控制器和ApiController的项目中,从ApiController和操作名称获取Url

C# 在包含控制器和ApiController的项目中,从ApiController和操作名称获取Url,c#,asp.net-mvc,asp.net-web-api,C#,Asp.net Mvc,Asp.net Web Api,现有项目的控制器继承自: Controller:RouteTable.Routes.MapRoute带有“{Controller}/{action}/{id}” ApiController:GlobalConfiguration。使用“api/{controller}/{id}”配置和回调MapRoute 一切正常,但我需要为这两种类型的控制器中的操作方法生成URL。鉴于: 从其中一个继承的控制器的名称或类型,以及 操作方法名称 那么,从web站点方面来说,我如何为web API方面生成正确

现有项目的控制器继承自:

  • Controller
    RouteTable.Routes.MapRoute
    带有
    “{Controller}/{action}/{id}”
  • ApiController
    GlobalConfiguration。使用
    “api/{controller}/{id}”
    配置
    和回调
    MapRoute
一切正常,但我需要为这两种类型的控制器中的操作方法生成URL。鉴于:

  • 从其中一个继承的控制器的名称或类型,以及
  • 操作方法名称
  • 那么,从web站点方面来说,我如何为web API方面生成正确的URL呢

    我现在使用反射获取操作和控制器名称,然后通过使用
    UrlHelper.action(actionName、controllerName、routeValueDictionary)
    获取网站路由的正确URL

    然而,这个方法(当然)是为WebAPI端生成这样的URL:
    /ApiControllerName/Get?parameter1=value
    ,当它需要
    /api/ApiControllerName?parameter1=value
    时,以及它是Get请求的单独知识

    用途:这是用于web站点的冒烟测试页面,该页面使用属性和反射来决定冒烟测试的内容。如果能够在整个项目中使用相同的属性就好了,而且如果能够使用正确的
    UrlHelper
    ,它知道路由表,并且能够生成正确的前缀,例如
    /api/
    ,而不是代码假设(可能是错误的),API路由是在
    API
    注册的,而不是,比如说,
    webapi

    更新

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

    我在这方面做了更多的研究,还没有找到解决方案。看起来,如果您知道相应路由的路由名称。还有一些可能的暗示和建议。但是,如果WebApi有多个路由,您如何知道哪个路由与您想要的控制器和操作匹配?重新实现MVC本身在选择控制器和操作方面已经做过的事情是愚蠢的。我想我可以使用每个WebApi路由从给定的参数构造一个URL,然后通过它的速度运行URL(使用上面的一些链接),看看它是否匹配所需的控制器。。。恶心

    一定有更简单的方法


    现在我不得不继续,但希望有人能帮助我。

    有一个库,允许您使用路由配置从控制器和操作创建URI。

    这看起来更像是一个黑客行为,但如果您仅计划将其用于测试,则值得一试。如前所述,您可以使用路由名称生成URL。因此,您可以获取所有路由名称并生成所有可能的URL。然后,您需要检查URL是否解析为您需要的操作。为此,您可以使用如下内容:。基本思想是,如果你有一个URL,那么在那里做一个假重定向,然后从框架中获取路由数据

    这里有几种方法:

    • 使用
      RouteUrl()
      方法:

      var url1 = Url.RouteUrl(new { id = 1, controller = "...",  httproute = true });
      
      var url2 = Url.HttpRouteUrl(null, new { id = 2, controller = ".." });
      
    技巧当然是
    httproute=true
    。设置此属性时,您会通知您只需要http路由(Web Api路由)

    • 使用
      HttpRouteUrl()
      方法:

      var url1 = Url.RouteUrl(new { id = 1, controller = "...",  httproute = true });
      
      var url2 = Url.HttpRouteUrl(null, new { id = 2, controller = ".." });
      
    • 另一种方法是直接使用routes和
      httproute
      值:

      var values = new RouteValueDictionary(new
      {
          id = 3,
          controller = "...",
          httproute = true
      });
      var url3 = RouteTable.Routes.GetVirtualPath(Request.RequestContext, values).VirtualPath;
      
    这三种方法基本相同。由于未指定路由,系统将尝试根据路由值查找第一个匹配项。例如,假设您有一个名为
    RestfulController
    ApiController
    ,web api路由的配置如下:

    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})
    在MVC
    控制器中,
    url
    中的值是
    /api/restful/123

    但如果您添加了新的路由约束TAPI:

    RouteUrl
    返回的url是
    /api2/restful/123


    在声明路线时,应注意顺序。如果在路由
    ConstraintApi
    之前添加了路由
    DefaultApi
    ,则生成的url是
    /api/restful/123

    ,看起来很有趣,可能正是我需要的,但同时它还没有为我准备好,因为“它需要一个
    HttpRequestMessage
    类的实例,该类由ASP.NET Web API为每个请求提供。获取此实例的首选方法是实现一个自定义的
    IHttpControllerActivator
    ,并从中创建RouteLink实例。“这意味着我必须做一些聪明的事情才能使它在web端工作(当然,web端没有
    HttpRequestMessage
    的实例)。这是一个有趣的想法。参数将如何发挥作用呢?也就是说,当操作方法仅因参数列表不同时,我如何可靠地生成一个URL,以命中所需的操作方法?此外,如果路由设置时没有路由名称呢?正如我所说的,这不是一个成熟的解决方案,而是一种黑客行为。因此,参数将尽可能有效因为你可以使用反射,它很可能只在你需要的情况下工作。(你在更新中提到,如果你有路由名称,可以生成Url,所以我只是认为你可以解决这个问题)对于没有名称的路由,您可以创建自己的
    Route
    RouteCollection
    类,该类保存路由名称,或者当未指定任何内容时,它会生成一个