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

我正在寻找这样的语法:

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

这将返回:

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


当前回答

这两种方法都有效:

  Uri final = new Uri(Regex.Replace(baseUrl + "/" + relativePath, "(?<!http:)/{2,}", "/"));

Or

  Uri final =new Uri(string.Format("{0}/{1}", baseUrl.ToString().TrimEnd('/'), relativePath.ToString().TrimStart('/')));

即,如果

baseUrl = "http://tesrurl.test.com/Int18"

and

relativePath = "To_Folder"

output = http://tesrurl.test.com/Int18/To_Folder

以下代码将出现一些错误:

 // If you use the below code, some issues will be there in the final URI
 Uri final = new Uri(baseUrl, relativePath);

其他回答

我必须指出,Path.Combine似乎也能直接实现这一点,至少在.NET 4上是如此。

好吧,我只是连接两个字符串并使用正则表达式来完成清理部分。

    public class UriTool
    {
        public static Uri Join(string path1, string path2)
        {
            string url = path1 + "/" + path2;
            url = Regex.Replace(url, "(?<!http:)/{2,}", "/");

            return new Uri(url);
        }
    }

因此,您可以这样使用:

    string path1 = "http://someaddress.com/something/";
    string path2 = "/another/address.html";
    Uri joinedUri = UriTool.Join(path1, path2);

    // joinedUri.ToString() returns "http://someaddress.com/something/another/address.html"

我使用此代码来解决问题:

string[] brokenBaseUrl = Context.Url.TrimEnd('/').Split('/');
string[] brokenRootFolderPath = RootFolderPath.Split('/');

for (int x = 0; x < brokenRootFolderPath.Length; x++)
{
    //if url doesn't already contain member, append it to the end of the string with / in front
    if (!brokenBaseUrl.Contains(brokenRootFolderPath[x]))
    {
        if (x == 0)
        {
            RootLocationUrl = Context.Url.TrimEnd('/');
        }
        else
        {
            RootLocationUrl += String.Format("/{0}", brokenRootFolderPath[x]);
        }
    }
}

所以我有另一种方法,类似于使用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属性。

我发现UriBuilder在这种情况下工作得很好:

UriBuilder urlb = new UriBuilder("http", _serverAddress, _webPort, _filePath);
Uri url = urlb.Uri;
return url.AbsoluteUri;

有关更多构造函数和文档,请参阅UriBuilder类-MSDN。