将相对baseUri与相对路径相结合

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

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

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

这仍然比我想要的有点麻烦,但它确实有效。

 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是〜/ path / to / images / profile.jpg

尝试:

 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”。

首先,感谢您对此帖的回复!

我制作了该方法的简化版本,省略了使用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; } 

上面的代码可能对其他想要公开提供此function的方法而不依赖于Uri或VirtualPathUtility但仅依赖于简单字符串的人有用。

当然可以轻松修改以返回Uri – 仍然保留解析字符串参数的好处:

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

使用上述两个代码示例:

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

jrummell的答案稍微更通用的版本接受第一个参数是绝对或相对的Uri是:

  ///  /// Combines two s. ///  /// Relative or absolute base uri. /// Uri to be appended. 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); } 

尝试:

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

您可以使用Path.Combine(string, string)来实现此目的。 如果它是一个相对URL,输出会有点时髦,但它很容易纠正 – 或者你可以简单地忽略这个问题,大多数用法仍然可以工作。

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

输出:〜/ path / to / images \ image.jpg