2008-09-24 32 views
59

Điều này có thể được giải thích dễ dàng hơn với một ví dụ. Tôi đang cố tìm cách chuyển URL tương đối, ví dụ: "/Foo.aspx" hoặc "~/Foo.aspx" vào URL đầy đủ, ví dụ: http://localhost/Foo.aspx. Bằng cách đó khi tôi triển khai để kiểm tra hoặc giai đoạn, nơi mà tên miền mà trang web chạy là khác nhau, tôi sẽ nhận được http://test/Foo.aspxhttp://stage/Foo.aspx.Làm cách nào để chuyển URL tương đối thành URL đầy đủ?

Bất kỳ ý tưởng nào?

+0

2 câu trả lời liên quan tại địa chỉ: http: // stackoverflow .com/questions/7413466/how-can-i-get-the-baseurl-of-site và http://stackoverflow.com/questions/3933662/in-asp-net-what-is-the-quickest-way -to-get-the-base-url-cho-một-yêu cầu –

Trả lời

57

Có một vở kịch với điều này (sửa đổi from here)

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

Tôi đã hy vọng có một cái gì đó được xây dựng trong ASP .NET vì vậy tôi không phải nhận được vào tất cả các doanh nghiệp nhìn vào các giao thức, cổng, vv nhưng điều này nên thực hiện công việc. – gilles27

+7

Chỉ cần lưu ý: Khi tôi sử dụng điều này tôi đã thêm Request.URL.Port giữa máy chủ và trang url để nó sẽ hoạt động trên máy chủ thử nghiệm Visual Web Dev. – ine

+0

@roviuser Tthis không liên quan gì tới MVC. Nó chỉ là một chức năng tiện ích để dính nó bất cứ nơi nào bạn muốn. – Oli

5

Đây là chức năng giúp đỡ tôi để làm điều này

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

Làm điều này vẫn làm việc cho bạn trong ASP.net 4.0? Tôi có một cách tiếp cận tương tự và tôi nhận được IP máy chủ như là người chủ, thay vì tên miền. Tại sao điều đó sẽ là? –

2

Đây là hàm mà tôi tạo ra để làm việc chuyển đổi.

//"~/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

Bạn chỉ cần tạo một URI mới sử dụng page.request.url và sau đó nhận được AbsoluteUri đó:

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

Điều này có vẻ xuất sắc trong sự đơn giản của nó, nhưng không phải 'Request.Url' thường bao gồm tên trang đã được yêu cầu? Tại sao không' OldFoo.aspx'collide với 'Foo.aspx'? (Nghĩa là: là' new Uri () 'tước URI cơ sở trước khi kết hợp nó với phần tương đối?) – ebyrob

+3

@ebyrob Hàm tạo Uri (Uri, string) không loại bỏ bất kỳ phần tương đối nào của tham số thứ nhất và sau đó kết hợp nó với tham số thứ 2. Các tài liệu MSDN trên [Uri constructor] (https://msdn.microsoft.com/en-us/library/9hst1w91 (v = vs.110) .aspx) không thực hiện điều này rõ ràng nhưng [fiddle test] (https: //dotnetfiddle.net/WHUjkY) xác minh hành vi. –

37

Cái này là được đánh đến chết nhưng tôi nghĩ rằng tôi muốn gửi giải pháp của riêng tôi mà Tôi nghĩ là sạch hơn nhiều câu trả lời khác.

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

Những phương pháp này thật tuyệt vời. Cảm ơn một tấn! Mở rộng tuyệt vời. Tôi đã thử một cái khác như thế này nhưng điều này sạch hơn nhiều, và tôi thích những thứ xâu chuỗi lại với nhau tốt hơn rất nhiều. Cảm ơn. – Ryan

+2

Tôi tìm thấy điều này. Cảm ơn. Tôi đã thêm một thay đổi nhỏ để tránh sơ đồ URl được mã hóa cứng: 'code' return url.Action (actionName, controllerName, routeValues, url.RequestContext.HttpContext.Request.Url.Scheme); 'code' –

+0

@ LSU.Net: Thêm thay đổi của bạn. Tôi nghĩ rằng đó là cách tôi có nó trong stash mã cá nhân của tôi quá. –

1

Đơn giản chỉ cần:

url = new Uri(baseUri, url); 
3

tôi nghĩ rằng tôi muốn chia sẻ cách tiếp cận của tôi để làm điều này trong ASP.NET MVC sử dụng lớp Uri và một số ma thuật mở rộng.

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

Bạn có thể sau đó đầu ra một đường dẫn tuyệt đối sử dụng:

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

Có vẻ một chút xấu xí có phương pháp lồng nhau gọi vì vậy tôi thích để mở rộng hơn nữa UrlHelper với các phương pháp hành động chung vì vậy mà tôi có thể làm:

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

hoặc

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

Lớp mở rộng đầy đủ như sau:

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

Trong ASP.NET MVC bạn có thể sử dụng quá tải của HtmlHelper hoặc UrlHelper rằng lấy các thông số hoặc host. Khi một trong các tham số này không trống, người trợ giúp tạo URL tuyệt đối. Đây là phương pháp tiện ích mở rộng tôi đang sử dụng:

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

Và sử dụng nó từ chế độ xem Dao cạo, ví dụ::

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

Câu hỏi cổ, nhưng tôi nghĩ tôi sẽ trả lời vì nhiều câu trả lời chưa hoàn chỉnh.

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

Điều này hoạt động như một tiện ích mở rộng của Trang, giống như ResolveUrl và ResolveClientUrl cho biểu mẫu web. Vui lòng chuyển đổi nó sang phần mở rộng HttpResponse nếu bạn muốn hoặc cần sử dụng nó trong môi trường không phải là webforms. Nó xử lý chính xác cả http và https, trên các cổng tiêu chuẩn và không chuẩn, và nếu có một thành phần tên người dùng/mật khẩu. Nó cũng không sử dụng bất kỳ chuỗi được mã hóa cứng nào (cụ thể là: //).

0

Đây là một cách tiếp cận. Điều này không quan tâm nếu chuỗi là tương đối hay tuyệt đối, nhưng bạn phải cung cấp một baseUri cho nó để sử dụng.

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

Trong một bối cảnh ASP.NET, bạn có thể làm điều này:

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

Modified từ câu trả lời khác cho công việc với localhost và các cổng ... im sử dụng cho ex. liên kết email. Bạn có thể gọi từ bất kỳ phần nào của ứng dụng, không chỉ trong một trang hoặc usercontrol, tôi đặt này trong toàn cầu không cần phải vượt qua HttpContext.Current.Request như tham số

  /// <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) 
        ); 

      } 
Các vấn đề liên quan