2011-02-07 35 views
13

Tôi đang tìm một cách sạch sẽ để kết hợp URI cơ sở tương đối với một đường dẫn tương đối khác. Tôi đã thử những điều sau đây, nhưng Uri(Uri, string)UriBuilder(Uri) yêu cầu tuyệt đối Uris (ném InvalidOperationException: Hoạt động này không được hỗ trợ cho một URI tương đối).Kết hợp base tương đốiUri với đường dẫn tương đối

// where Settings.Default.ImagesPath is "~/path/to/images" 
// attempt 1 
_imagePath = new Uri(Settings.Default.ImagesPath, image); 

// attempt 2 
UriBuilder uriBuilder = new UriBuilder(Settings.Default.ImagesPath); 
uriBuilder.Path += image; 
_imagePath = uriBuilder.Uri; 

Tôi không muốn làm bất cứ thao tác chuỗi xấu xí để đảm bảo con đường cơ sở kết thúc bằng một dấu gạch chéo vv

Trả lời

17

này vẫn là một chút hỗn độn hơn tôi muốn, nhưng nó hoạt động.

public static class UriExtensions 
{ 
    public static Uri Combine(this Uri relativeBaseUri, Uri relativeUri) 
    { 
     if (relativeBaseUri == null) 
     { 
      throw new ArgumentNullException("relativeBaseUri"); 
     } 

     if (relativeUri == null) 
     { 
      throw new ArgumentNullException("relativeUri"); 
     } 

     string baseUrl = VirtualPathUtility.AppendTrailingSlash(relativeBaseUri.ToString()); 
     string combinedUrl = VirtualPathUtility.Combine(baseUrl, relativeUri.ToString()); 

     return new Uri(combinedUrl, UriKind.Relative); 
    } 
} 

Dưới đây là một cách sử dụng ví dụ:

Uri imageUrl = new Uri("profile.jpg", UriKind.Relative); 
Uri baseImageUrl = new Uri("~/path/to/images", UriKind.Relative); 
Uri combinedImageUrl = baseImageUrl.Combine(image); 

Các combinedImageUrl là ~/path/to/images/profile.jpg

-1

Hãy thử:

UriBuilder uriBuilder = new UriBuilder(Settings.Default.ImagesRealtivePath); 
uriBuilder.Path += image; 
_imagePath = uriBuilder.Uri; 
+0

Điều này giống như ví dụ thử của tôi 2. Nó ném "InvalidOperationException: Hoạt động này không được hỗ trợ cho một URI tương đối" – jrummell

-3

Bạn có thể chỉ cần sử dụng Path.Combine(string, string) để đạt được điều này. Nếu đó là một URL tương đối, đầu ra sẽ hơi sôi nổi, nhưng nó sẽ đủ dễ dàng để sửa hoặc bạn chỉ có thể bỏ qua vấn đề và hầu hết các tập quán vẫn hoạt động.

Path.Combine("~/path/to/images", "image.jpg"); 

Output: ~/path/to/images \ image.jpg

+3

Có một số lý do điều này đã được bỏ phiếu không? Downvoting mà không có một bình luận là vô cùng vô ích. –

+2

Không phải là downvoter, nhưng nó đặt trong một dấu gạch chéo ngược thay vì một dấu gạch chéo về phía trước, không chính xác cho các URL. Đặc biệt, các liên kết đó thực sự sẽ không hoạt động trên Firefox trên máy Mac. – user12861

+0

Path.Combine dành cho đường dẫn tệp cục bộ, không phải URI – StuartQ

4

Hãy thử:

UriBuilder builder = new UriBuilder(); 
Uri baseUri = builder.Uri; 
builder.Path = Settings.Default.ImagesRealtivePath; 
if (!builder.Path.EndsWith("/")) 
    builder.Path += "/"; 
_imagePath = baseUri.MakeRelativeUri(new Uri(builder.Uri, image)); 

này sẽ trở lại chuỗi "~/path/to/images/image.jpg".

1

Trước hết, cảm ơn phản hồi về bài đăng này!

Tôi đã thực hiện phiên bản đơn giản của phương pháp, bỏ qua "độ phức tạp" khi sử dụng lớp Uri. Phương thức này chỉ nhận các chuỗi như các tham số và cũng trả về một chuỗi.

public static string MakeRelativeUrl(params string[] relativePaths) 
{ 
    var res = "~/"; 
    foreach (var relativePath in relativePaths) 
    { 
     string baseUrl = VirtualPathUtility.AppendTrailingSlash(res); 
     res = VirtualPathUtility.Combine(baseUrl, relativePath); 
    } 
    return res; 
} 

Mã trên có thể hữu ích cho những người muốn phơi bày phương pháp cung cấp chức năng này mà không bị phụ thuộc vào Uri hoặc VirtualPathUtility, nhưng chỉ đơn giản là chuỗi.

thể dĩ nhiên dễ dàng được sửa đổi để trở Uri - vẫn giữ lợi ích của phân tích các thông số chuỗi:

public static Uri MakeRelativeUrl(params string[] relativePaths) 
{ 
    var res = "~/"; 
    foreach (var relativePath in relativePaths) 
    { 
     string baseUrl = VirtualPathUtility.AppendTrailingSlash(res); 
     res = VirtualPathUtility.Combine(baseUrl, relativePath); 
    } 
    return new Uri(res, UriKind.Relative); 
} 

Sử dụng cả hai ví dụ mã trên:

Image.ImageUrl = MakeRelativeUrl("path", "to", "images", "image.jpg").ToString(); 
// Image.ImageUrl == "~/path/to/images/image.jpg" 
1

Một phiên bản hơi tổng quát hơn câu trả lời của jrummell chấp nhận tham số đầu tiên là số tuyệt đối hoặc tương đối Uri là:

/// <summary> 
    /// Combines two <see cref="Uri"/>s. 
    /// </summary> 
    /// <param name="baseUri">Relative or absolute base uri.</param> 
    /// <param name="relativeUri">Uri to be appended.</param> 
    public static Uri Combine(this Uri baseUri, Uri relativeUri) 
    { 
     if (baseUri == null) throw new ArgumentNullException("baseUri"); 
     if (relativeUri == null) throw new ArgumentNullException("relativeUri"); 

     string baseUrl = VirtualPathUtility.AppendTrailingSlash(baseUri.ToString()); 
     string combinedUrl = VirtualPathUtility.Combine(baseUrl, relativeUri.ToString()); 

     return new Uri(combinedUrl, baseUri.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative); 
    } 
Các vấn đề liên quan