Path.Combine很方便,但是.NET框架中是否有类似的URL函数?

我正在寻找这样的语法:

Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")

这将返回:

"http://MyUrl.com/Images/Image.jpg"


当前回答

最近,Combine方法被添加到Energy.Core包中,所以您可能希望使用它来连接URL部分。

    string url;
    url = Energy.Base.Url.Combine("https://www.youtube.com", "watch?v=NHCgbs3TcYg");
    Console.WriteLine(url);
    url = Energy.Base.Url.Combine("https://www.youtube.com", "watch?v=NHCgbs3TcYg", "t=150");
    Console.WriteLine(url);

此外,它将识别参数部分,因此它将按照您的预期工作(用斜线连接路径,用&符号连接参数)。

https://www.youtube.com/watch?v=NHCgbs3TcYghttps://www.youtube.com/watch?v=NHCgbs3TcYg&t=150

Energy.Base.Url类文档

NuGet图库上的软件包

代码示例

其他回答

所以我有另一种方法,类似于使用UriBuilder的每个人。

我不想拆分我的BaseUrl(它可以包含路径的一部分,例如。http://mybaseurl.com/dev/)正如javajavajavajava所做的那样。

下面的代码片段显示了代码+测试。

注意:此解决方案降低了主机并附加了一个端口。如果不需要这样做,可以通过例如利用UriBuilder的Uri属性来编写字符串表示。

  public class Tests
  {
         public static string CombineUrl (string baseUrl, string path)
         {
           var uriBuilder = new UriBuilder (baseUrl);
           uriBuilder.Path = Path.Combine (uriBuilder.Path, path);
           return uriBuilder.ToString();
         }

         [TestCase("http://MyUrl.com/", "/Images/Image.jpg", "http://myurl.com:80/Images/Image.jpg")]
         [TestCase("http://MyUrl.com/basePath", "/Images/Image.jpg", "http://myurl.com:80/Images/Image.jpg")]
         [TestCase("http://MyUrl.com/basePath", "Images/Image.jpg", "http://myurl.com:80/basePath/Images/Image.jpg")]
         [TestCase("http://MyUrl.com/basePath/", "Images/Image.jpg", "http://myurl.com:80/basePath/Images/Image.jpg")]
         public void Test1 (string baseUrl, string path, string expected)
         {
           var result = CombineUrl (baseUrl, path);

           Assert.That (result, Is.EqualTo (expected));
         }
  }

在Windows 10上使用.NET Core 2.1进行测试。

为什么这样做?

尽管Path.Combine将返回反斜杠(至少在Windows上),但UriBuilder在路径设置器中处理这种情况。

摘自https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/src/System/UriBuilder.cs(注意调用字符串。替换)

[AllowNull]
public string Path
{
      get
      {
          return _path;
      }
      set
      {
          if ((value == null) || (value.Length == 0))
          {
              value = "/";
          }
          _path = Uri.InternalEscapeString(value.Replace('\\', '/'));
          _changed = true;
      }
 }

这是最好的方法吗?

当然,这个解决方案非常自我描述(至少在我看来)。但是,您依赖的是.NETAPI中的未记录(至少我在快速谷歌搜索中没有发现任何内容)“功能”。这可能会随着将来的版本而改变,因此请将方法与测试结合起来。

中有测试https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs(Path_Get_Set),用于检查\是否正确转换。

附带说明:如果Uri将用于System.Uri构造函数,则也可以直接使用UriBuilder.Uri属性。

上面有托德·梅尼尔(Todd Menier)的评论,Flurl包括一个Url.Combine。

更多详情:

Url.Combine基本上是Url的Path.Combine,确保部分之间只有一个分隔符:

var url = Url.Combine(
    "http://MyUrl.com/",
    "/too/", "/many/", "/slashes/",
    "too", "few?",
    "x=1", "y=2"
// result: "http://www.MyUrl.com/too/many/slashes/too/few?x=1&y=2" 

在NuGet上获取Flurl.Http:

PM>安装包Flurl.Http

或者获取没有HTTP功能的独立URL生成器:

PM>安装程序包Flurl

您使用Uri.TryCreate(…):

Uri result = null;

if (Uri.TryCreate(new Uri("http://msdn.microsoft.com/en-us/library/"), "/en-us/library/system.uri.trycreate.aspx", out result))
{
    Console.WriteLine(result);
}

将返回:

http://msdn.microsoft.com/en-us/library/system.uri.trycreate.aspx

我认为这应该给你更多的灵活性,因为你可以处理任意多的路径段:

public static string UrlCombine(this string baseUrl, params string[] segments)
=> string.Join("/", new[] { baseUrl.TrimEnd('/') }.Concat(segments.Select(s => s.Trim('/'))));

如果您不想在ASP.NET Core(也在Microsoft.Owin中提供)中添加第三方依赖项(如Flurl)或创建自定义扩展方法,则可以使用PathString来构建URI路径。然后,可以使用URI和UriBuilder的组合创建完整的URI。

在这种情况下,应为:

new Uri(new UriBuilder("http", "MyUrl.com").Uri, new PathString("/Images").Add("/Image.jpg").ToString())

这提供了所有组成部分,而无需在基URL中指定分隔符。不幸的是,PathString要求在每个字符串前面加上/,否则它实际上会引发ArgumentException!但至少您可以以易于单元测试的方式确定地构建URI。