【问题标题】:Get an instance of WebApi UrlHelper from inside an Mvc Action从 Mvc Action 中获取 WebApi UrlHelper 的实例
【发布时间】:2013-05-05 15:37:44
【问题描述】:

我在同一个项目中运行 WebApi 和 Mvc(因此它们在进程中)。 Mvc 主要用于服务资产(页面和生成的下载)和用于 ajax 数据请求的 web api。

为了实现 RESTish,大多数 WebApi 请求都包含一组链接,这些链接由以下类生成:

public class ApiLinkMaker
{
    public ApiLinkMaker(UrlHelper url, string authority) {
        this.url = url;
        this.authority = authority;
    }
    public ApiLinkMaker(ApiController controller)
        : this(controller.Url, controller.Request.RequestUri.Authority) { }

    public string MakeLink(string controller, string id) {
        return "//" + authority + url.Route("DefaultApi", new { controller = controller, id = id });
    }
}

那里还有其他一些方法,但这确实是事情的核心,而且效果很好。

现在我想优化一个特定的页面。以前我有两个请求

  1. 下载html
  2. 执行 Ajax 查询以获取一些数据(和一些链接)

现在我意识到,为了优化目的,在这种情况下最好只做一个。

  1. 下载已嵌入 JSON 数据的 html。

问题是由于 html 是由 Mvc 生成的,所以我无法创建一个似乎可以工作的 Api UrlHelper。

我试过了

var url = new UrlHelper(new HttpRequestMessage(verb, controller.Request.Url.AbsoluteUri));
if (!url.Request.Properties.ContainsKey(HttpPropertyKeys.HttpConfigurationKey)) //http://stackoverflow.com/questions/11053598/how-to-mock-the-createresponset-extension-method-on-httprequestmessage
   url.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());

但这仍然会爆炸

System.ArgumentException was unhandled by user code
  HResult=-2147024809
  Message=A route named 'DefaultApi' could not be found in the route collection.
Parameter name: name
  Source=System.Web.Http
  ParamName=name
  StackTrace:
       at System.Web.Http.HttpRouteCollection.GetVirtualPath(HttpRequestMessage request, String name, IDictionary`2 values)
       at System.Web.Http.Routing.UrlHelper.GetHttpRouteHelper(HttpRequestMessage request, String routeName, IDictionary`2 routeValues)
       at System.Web.Http.Routing.UrlHelper.GetHttpRouteHelper(HttpRequestMessage request, String routeName, Object routeValues)
       at System.Web.Http.Routing.UrlHelper.Route(String routeName, Object routeValues)
       at MyProject.Models.ApiLinkMaker.MakeLink(String controller, String id) in w:\MyProject\Models\ApiLinkMaker.cs:line 42
       ...

这让我觉得我做错了——我需要以某种方式从 api 路由配置创建 url 帮助程序。

【问题讨论】:

    标签: asp.net asp.net-web-api


    【解决方案1】:

    为什么要创建一个? UriHelper 的一个实例作为 MVC Controller 和 ApiController 类上的属性公开。

        public ActionResult Index()
        {
            string url = Url.RouteUrl("DefaultApi", new {httproute = "", controller = "test"});
            return View();
        }
    

    编辑:更新代码。虽然 url helper 不同,但您可以使用 MVC url helper 来解析 web api url。

    Edit2:如果你想从 Mvc UrlHelper 获取 webapi 路由,正确的方法是

    string url = Url.HttpRouteUrl("DefaultApi", new {httproute = "", controller = "test"});
    

    【讨论】:

    • 因为这里没有携带WebApi配置。 MvcController.UrlHelperApiController.UrlHelper 实际上是不同的类,而不仅仅是不同的类实例。
    • @GeorgeMauer 虽然是这样,但您仍然可以从 MVC 控制器 url 帮助程序获取 Web api url。我已经更新了代码。
    • 您的代码不正确,虽然您似乎可以从 mvc url 帮助程序访问 web api url,但您必须使用 Url.HttpRouteUrl。就我而言,由于我想将链接构建代码保留在 ApiLinkMaker 中,我想我可以直接传递一个委托而不是 UrlHelper。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多