【问题标题】:How do I turn a relative URL into a full URL?如何将相对 URL 转换为完整 URL?
【发布时间】:2010-09-12 16:17:22
【问题描述】:

这可能用一个例子更容易解释。我正在尝试找到一种转换相对 URL 的方法,例如"/Foo.aspx" 或 "~/Foo.aspx" 变成一个完整的 URL,例如http://localhost/Foo.aspx。这样,当我部署到测试或阶段时,站点运行的域不同,我会得到http://test/Foo.aspxhttp://stage/Foo.aspx

有什么想法吗?

【问题讨论】:

标签: asp.net


【解决方案1】:

您只需要使用page.request.url 创建一个新的URI,然后获取它的AbsoluteUri

New System.Uri(Page.Request.Url, "Foo.aspx").AbsoluteUri

【讨论】:

  • 这看起来很简单,但Request.Url 通常不包含已经请求的页面名称吗?为什么OldFoo.aspxFoo.aspx不冲突? (即:new Uri() 是在将基本 URI 与相关部分组合之前剥离它吗?)
  • @ebyrob Uri(Uri, string) 构造函数会剥离第一个参数的任何相关部分,然后将其与第二个参数组合。 Uri constructor 上的 MSDN 文档没有说明这一点,但 fiddle test 验证了行为。
【解决方案2】:

在ASP.NET MVC中,可以使用Url.Content(relativePath)转换成绝对Url

【讨论】:

    【解决方案3】:

    从其他答案修改为与 localhost 和其他端口一起工作......我正在使用 ex。电子邮件链接。您可以从应用程序的任何部分调用,不仅在页面或用户控件中,我将其放在 Global 中,不需要将 HttpContext.Current.Request 作为参数传递

                /// <summary>
                ///  Return full URL from virtual relative path like ~/dir/subir/file.html
                ///  usefull in ex. external links
                /// </summary>
                /// <param name="rootVirtualPath"></param>
                /// <returns></returns>
                public static string GetAbsoluteFullURLFromRootVirtualPath(string rootVirtualPath)
                {
    
                    return string.Format("http{0}://{1}{2}{3}",
                        (HttpContext.Current.Request.IsSecureConnection) ? "s" : ""
                        , HttpContext.Current.Request.Url.Host
                        , (HttpContext.Current.Request.Url.IsDefaultPort) ? "" : ":" + HttpContext.Current.Request.Url.Port
                        , VirtualPathUtility.ToAbsolute(rootVirtualPath)
                        );
    
                }
    

    【讨论】:

      【解决方案4】:

      这是一种方法。这不关心字符串是相对的还是绝对的,但您必须提供一个 baseUri 供它使用。

          /// <summary>
          /// This function turns arbitrary strings containing a 
          /// URI into an appropriate absolute URI.  
          /// </summary>
          /// <param name="input">A relative or absolute URI (as a string)</param>
          /// <param name="baseUri">The base URI to use if the input parameter is relative.</param>
          /// <returns>An absolute URI</returns>
          public static Uri MakeFullUri(string input, Uri baseUri)
          {
              var tmp = new Uri(input, UriKind.RelativeOrAbsolute);
              //if it's absolute, return that
              if (tmp.IsAbsoluteUri)
              {
                  return tmp;
              }
              // build relative on top of the base one instead
              return new Uri(baseUri, tmp);
          }
      

      在 ASP.NET 上下文中,您可以这样做:

      Uri baseUri = new Uri("http://yahoo.com/folder");
      Uri newUri = MakeFullUri("/some/path?abcd=123", baseUri);
      //
      //newUri will contain http://yahoo.com/some/path?abcd=123
      //
      Uri newUri2 = MakeFullUri("some/path?abcd=123", baseUri);
      //
      //newUri2 will contain http://yahoo.com/folder/some/path?abcd=123
      //
      Uri newUri3 = MakeFullUri("http://google.com", baseUri);
      //
      //newUri3 will contain http://google.com, and baseUri is not used at all.
      //
      

      【讨论】:

        【解决方案5】:

        古老的问题,但我想我会回答它,因为许多答案都不完整。

        public static string ResolveFullUrl(this System.Web.UI.Page page, string relativeUrl)
        {
            if (string.IsNullOrEmpty(relativeUrl))
                return relativeUrl;
        
            if (relativeUrl.StartsWith("/"))
                relativeUrl = relativeUrl.Insert(0, "~");
            if (!relativeUrl.StartsWith("~/"))
                relativeUrl = relativeUrl.Insert(0, "~/");
        
            return $"{page.Request.Url.Scheme}{Uri.SchemeDelimiter}{page.Request.Url.Authority}{VirtualPathUtility.ToAbsolute(relativeUrl)}";
        }
        

        这可以作为页面外的扩展,就像 Web 表单的 ResolveUrl 和 ResolveClientUrl 一样。如果您想或需要在非网络表单环境中使用它,请随意将其转换为 HttpResponse 扩展。它可以正确处理标准和非标准端口上的 http 和 https,以及是否存在用户名/密码组件。它也不使用任何硬编码字符串(即://)。

        【讨论】:

          【解决方案6】:

          玩玩这个(修改from here

          public string ConvertRelativeUrlToAbsoluteUrl(string relativeUrl) {
              return string.Format("http{0}://{1}{2}",
                  (Request.IsSecureConnection) ? "s" : "", 
                  Request.Url.Host,
                  Page.ResolveUrl(relativeUrl)
              );
          }
          

          【讨论】:

          • 我希望 ASP .NET 有内置的东西,所以我不必涉足查看协议、端口等的所有业务,但这应该可以完成工作。跨度>
          • 请注意:当我使用它时,我在主机和页面 url 之间添加了 Request.URL.Port,因此它可以在 Visual Web Dev 测试服务器上运行。
          • @roviuser 这与 MVC 无关。它只是一个实用功能,所以可以随心所欲地粘贴它。
          • 如果端口不是默认端口 (80),这将不起作用。此外,空字符文字对我也不起作用。 Page.ResolveUrl 只能在 Page 的上下文中调用。我将代码调整为:return string.Format("{0}://{1}{2}{3}", (Request.IsSecureConnection) ? "https" : "http", Request.Url.Host, (Request.Url.Port == 80) ? "" : ":"+Request.Url.Port.ToString(), VirtualPathUtility.ToAbsolute(relativeUrl)
          【解决方案7】:

          在 ASP.NET MVC 中,您可以使用采用 protocolhost 参数的 HtmlHelperUrlHelper 的重载。当这些参数中的任何一个不为空时,帮助程序生成一个绝对 URL。这是我正在使用的扩展方法:

          public static MvcHtmlString ActionLinkAbsolute<TViewModel>(
              this HtmlHelper<TViewModel> html, 
              string linkText, 
              string actionName, 
              string controllerName, 
              object routeValues = null,
              object htmlAttributes = null)
          {
              var request = html.ViewContext.HttpContext.Request;
              var url = new UriBuilder(request.Url);
              return html.ActionLink(linkText, actionName, controllerName, url.Scheme, url.Host, null, routeValues, htmlAttributes);
          }
          

          并从 Razor 视图中使用它,例如:

           @Html.ActionLinkAbsolute("Click here", "Action", "Controller", new { id = Model.Id }) 
          

          【讨论】:

            【解决方案8】:

            我想我会分享我在 ASP.NET MVC 中使用 Uri 类和一些扩展魔法的方法。

            public static class UrlHelperExtensions
            {
                public static string AbsolutePath(this UrlHelper urlHelper, 
                                                  string relativePath)
                {
                    return new Uri(urlHelper.RequestContext.HttpContext.Request.Url,
                                   relativePath).ToString();
                }
            }
            

            然后您可以使用以下命令输出绝对路径:

            // gives absolute path, e.g. https://example.com/customers
            Url.AbsolutePath(Url.Action("Index", "Customers"));
            

            嵌套的方法调用看起来有点难看,所以我更喜欢用常见的操作方法进一步扩展UrlHelper,这样我就可以做到:

            // gives absolute path, e.g. https://example.com/customers
            Url.AbsoluteAction("Index", "Customers");
            

            Url.AbsoluteAction("Details", "Customers", new{id = 123});
            

            完整的扩展类如下:

            public static class UrlHelperExtensions
            {
                public static string AbsolutePath(this UrlHelper urlHelper, 
                                                  string relativePath)
                {
                    return new Uri(urlHelper.RequestContext.HttpContext.Request.Url,
                                   relativePath).ToString();
                }
            
                public static string AbsoluteAction(this UrlHelper urlHelper, 
                                                    string actionName, 
                                                    string controllerName)
                {
                    return AbsolutePath(urlHelper, 
                                        urlHelper.Action(actionName, controllerName));
                }
            
                public static string AbsoluteAction(this UrlHelper urlHelper, 
                                                    string actionName, 
                                                    string controllerName, 
                                                    object routeValues)
                {
                    return AbsolutePath(urlHelper, 
                                        urlHelper.Action(actionName, 
                                                         controllerName, routeValues));
                }
            }
            

            【讨论】:

              【解决方案9】:

              这个已经被打死了,但我想我会发布我自己的解决方案,我认为它比许多其他答案更干净。

              public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName, object routeValues)
              {
                  return url.Action(actionName, controllerName, routeValues, url.RequestContext.HttpContext.Request.Url.Scheme);
              }
              
              public static string AbsoluteContent(this UrlHelper url, string path)
              {
                  Uri uri = new Uri(path, UriKind.RelativeOrAbsolute);
              
                  //If the URI is not already absolute, rebuild it based on the current request.
                  if (!uri.IsAbsoluteUri)
                  {
                      Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
                      UriBuilder builder = new UriBuilder(requestUrl.Scheme, requestUrl.Host, requestUrl.Port);
              
                      builder.Path = VirtualPathUtility.ToAbsolute(path);
                      uri = builder.Uri;
                  }
              
                  return uri.ToString();
              }
              

              【讨论】:

              • 这些方法很棒。万分感谢!很棒的扩展。我尝试了另一个这样的方法,但这更干净,我更喜欢把东西串起来。谢谢。
              • 我找到了这个。谢谢。我添加了一个避免硬编码 URl 方案的细微更改:code return url.Action(actionName, controllerName, routeValues, url.RequestContext.HttpContext.Request.Url.Scheme); code
              • @LSU.Net:添加您的更改。我认为这也是我在个人代码存储中拥有它的方式。
              • +1 这很好用,只是返回的 URL 包含请求 URL 的查询字符串。我建议的编辑解决了这个问题。
              • 关闭!不幸的是,如果您尝试设置的绝对路径包含查询字符串,UriBuilder 将无法识别它。
              【解决方案10】:

              简单地说:

              url = new Uri(baseUri, url);
              

              【讨论】:

                【解决方案11】:

                这是我为进行转换而创建的辅助函数。

                //"~/SomeFolder/SomePage.aspx"
                public static string GetFullURL(string relativePath)
                {
                   string sRelative=Page.ResolveUrl(relativePath);
                   string sAbsolute=Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery,sRelative);
                   return sAbsolute;
                }
                

                【讨论】:

                  【解决方案12】:

                  这是我的辅助函数

                  public string GetFullUrl(string relativeUrl) {
                      string root = Request.Url.GetLeftPart(UriPartial.Authority);
                      return root + Page.ResolveUrl("~/" + relativeUrl) ;
                  }
                  

                  【讨论】:

                  • 这在 ASP.net 4.0 中仍然适用于您吗?我有一个类似的方法,我将服务器 IP 作为 root,而不是域。为什么会这样?
                  【解决方案13】:

                  使用 .NET Uri 类来组合您的相对路径和主机名。
                  http://msdn.microsoft.com/en-us/library/system.uri.aspx

                  【讨论】:

                  • 具体来说,System.Uri(System.Uri(base_uri), relative_uri).AbsoluteUri
                  猜你喜欢
                  • 2013-06-29
                  • 1970-01-01
                  • 2014-12-12
                  • 1970-01-01
                  • 2011-11-19
                  • 1970-01-01
                  • 2021-07-28
                  • 1970-01-01
                  相关资源
                  最近更新 更多