2008-09-24 4 views
59

Это, вероятно, объясняется более легко с примера. Я пытаюсь найти способ превратить относительный URL-адрес, например. "/Foo.aspx" или "~/Foo.aspx" в полный URL-адрес, например. http://localhost/Foo.aspx. Таким образом, когда я развертываю для тестирования или стадии, где домен, под которым работает сайт, отличается, я получаю http://test/Foo.aspx и http://stage/Foo.aspx.Как превратить относительный URL в полный URL?

Любые идеи?

+0

2 связанных ответы по адресу: // StackOverflow .com/вопросы/7413466/how-can-i-get-the-baseurl-of-site и http://stackoverflow.com/questions/3933662/in-asp-net-what-is-the-quickest-way -to-get-the-base-url-for-a-request – 2013-07-10 19:41:16

ответ

57

поиграйте с этим (модифицированный from here)

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

Я надеялся, что в ASP.NET есть что-то встроенное, поэтому мне не нужно заниматься всеми делами о протоколах, портах и ​​т. д. но это должно выполнять эту работу. – gilles27 2008-09-24 09:49:58

+7

Просто примечание: когда я использовал это, я добавил Request.URL.Port между хостом и URL-адресом страницы, чтобы он работал на сервере тестирования Visual Web Dev. – ine 2008-10-15 19:57:06

+0

@roviuser Это не имеет ничего общего с MVC. Это просто служебная функция, поэтому придерживайтесь ее там, где хотите. – Oli 2012-08-31 14:03:52

5

Это моя вспомогательная функция, чтобы сделать это

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

Это вспомогательная функция, которую я создал, чтобы сделать преобразование.

//"~/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; 
} 
30

Вам просто нужно создать новый URI с помощью page.request.url, а затем получить AbsoluteUri о том, что:

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

Это один был избить до смерти, но я думал, что я отправлю свое собственное решение, которое Я думаю, что чище, чем многие другие ответы.

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(); 
} 
1

Просто:

url = new Uri(baseUri, url); 
3

Я думал, что я разделю свой подход к выполнению этого в 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)); 
    } 
} 
1

В ASP.NET MVC можно использовать перегруженные HtmlHelper или UrlHelper, которые принимают или host параметров. Когда любой из этих параметров не пуст, хелперы генерируют абсолютный 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 }) 
0

Древний вопрос, но я думал, что отвечу на него, так как многие ответы неполны.

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)}"; 
} 

Это работает как расширение выходной страницы, так же, как и ResolveUrl ResolveClientUrl для WebForms. Не стесняйтесь преобразовывать его в расширение HttpResponse, если хотите или нужно использовать его в среде без веб-форм. Он правильно обрабатывает как http, так и https, на стандартных и нестандартных портах, и если есть компонент имени пользователя/пароля. Он также не использует жестко закодированные строки (а именно: //).

0

Вот такой подход. Это не имеет значения, является ли строка относительной или абсолютной, но вы должны предоставить 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. 
// 
0

Измененный другой ответ для работы с LOCALHOST и другими портами ... им с помощью напр. электронной почты. Вы можете позвонить из любой части приложения, а не только на странице или UserControl, я положил это в 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) 
        ); 

      } 
Смежные вопросы