【问题标题】:Combine relative baseUri with relative path将相对 baseUri 与相对路径相结合
【发布时间】:2011-02-07 19:17:28
【问题描述】:

我正在寻找一种将相对基本 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;

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

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

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

    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

    【讨论】:

      【解决方案2】:

      试试:

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

      【讨论】:

        【解决方案3】:

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

        我制作了该方法的简化版本,跳过了使用 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 - 仍然保留解析字符串参数的好处:

        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"
        

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:

            试试:

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

            【讨论】:

            • 这与我的尝试 2 示例相同。它抛出“InvalidOperationException:相对 URI 不支持此操作”
            【解决方案6】:

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

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

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

            【讨论】:

            • 是否有某些原因被否决了?在没有评论的情况下投反对票是非常无益的。
            • 不是反对者,但它使用反斜杠而不是正斜杠,这对于 URL 不正确。特别是这些链接实际上不适用于 Mac 上的 Firefox。
            • Path.Combine 用于本地文件路径,而不是 URIs
            • 那么 .NET 框架中是否已经存在像 Path.Combine 这样简单的东西?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-11
            • 2018-06-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-12
            相关资源
            最近更新 更多