2011-02-07 53 views
13

我正在寻找一种干净的方式来将相对基础Uri与另一个相对路径结合起来。我试过以下,但Uri(Uri, string)UriBuilder(Uri)要求绝对Uris(抛出InvalidOperationException:此操作不支持相对URI)。结合相对baseUri与相对路径

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

我不想做任何丑陋的字符串操作,以确保基本路径以斜线结束,等

回答

17

这仍然是一个有点混乱,比我想的,但它的工作原理。

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

下面是一个例子用法:

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

的combinedImageUrl是 〜/路径/到/图片/ profile.jpg

-1

尝试:

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

这与我的尝试2示例相同。它引发“InvalidOperationException:此操作不支持相对URI” – jrummell 2011-02-07 19:28:03

-3

你可以只使用​​为了达成这个。如果它是一个相对URL,输出将会有点时髦,但是很容易纠正 - 或者你可以忽略这个问题,大多数用法仍然可以工作。

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

输出:〜/路径/到/图片\ image.jpg的

+3

有没有一些原因,这是downvoted?在没有评论的情况下下调是非常无益的。 – 2011-03-30 20:50:12

4

尝试:

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

这将返回字符串“〜/ path/to/images/image.jpg”。

1

首先,感谢对这篇文章的回复!

我做了一个简化版的方法,跳过了使用Uri类的“复杂性”。该方法只将字符串作为参数,并且还返回一个字符串。

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

上面的代码可能是其他人谁愿意揭露提供此功能的方法不依赖于任何URI或VirtualPathUtility只有简单的字符串是有用的,但是。

当然也可以很容易地修改,以返回URI - 仍然保持解析字符串参数的好处:

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

稍微更广义的版本:

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

两个上面的代码示例使用jrummell的答案,接受第一个参数是绝对或相对的Uri是:

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