Path.Combine for URLs?

前端 未结 30 2490
不思量自难忘°
不思量自难忘° 2020-11-22 14:28

Path.Combine is handy, but is there a similar function in the .NET framework for URLs?

I\'m looking for syntax like this:

Url.Combine(\"http://MyUrl.         


        
30条回答
  •  暖寄归人
    2020-11-22 15:21

    So I have another approach, similar to everyone who used UriBuilder.

    I did not want to split my BaseUrl (which can contain a part of the path - e.g. http://mybaseurl.com/dev/) as javajavajavajavajava did.

    The following snippet shows the code + Tests.

    Beware: This solution lowercases the host and appends a port. If this is not desired, one can write a string representation by e.g. leveraging the Uri Property of UriBuilder.

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

    Tested with .NET Core 2.1 on Windows 10.

    Why does this work?

    Even though Path.Combine will return Backslashes (on Windows atleast), the UriBuilder handles this case in the Setter of Path.

    Taken from https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/src/System/UriBuilder.cs (mind the call to string.Replace)

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

    Is this the best approach?

    Certainly this solution is pretty self describing (at least in my opinion). But you are relying on undocumented (at least I found nothing with a quick google search) "feature" from the .NET API. This may change with a future release so please cover the Method with Tests.

    There are tests in https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs (Path_Get_Set) which check, if the \ is correctly transformed.

    Side Note: One could also work with the UriBuilder.Uri property directly, if the uri will be used for a System.Uri ctor.

提交回复
热议问题