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

我正在寻找这样的语法:

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

这将返回:

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


当前回答

这可能是一个合适的简单解决方案:

public static string Combine(string uri1, string uri2)
{
    uri1 = uri1.TrimEnd('/');
    uri2 = uri2.TrimStart('/');
    return string.Format("{0}/{1}", uri1, uri2);
}

其他回答

//阅读以上所有示例,结果创建了我自己:

static string UrlCombine(params string[] items)
{
    if (items?.Any() != true)
    {
        return string.Empty;
    }

    return string.Join("/", items.Where(u => !string.IsNullOrWhiteSpace(u)).Select(u => u.Trim('/', '\\')));
}

//用法

UrlCombine("https://microsoft.com","en-us")

组合URL的多个部分可能有点棘手。可以使用双参数构造函数Uri(baseUri、relativeUri),也可以使用Uri.TryCreate()实用程序函数。

在任何一种情况下,您都可能会返回错误的结果,因为这些方法会不断截断第一个参数baseUri的相对部分,例如http://google.com/some/thing到http://google.com.

为了能够将多个部分合并为最终URL,可以复制以下两个函数:

    public static string Combine(params string[] parts)
    {
        if (parts == null || parts.Length == 0) return string.Empty;

        var urlBuilder = new StringBuilder();
        foreach (var part in parts)
        {
            var tempUrl = tryCreateRelativeOrAbsolute(part);
            urlBuilder.Append(tempUrl);
        }
        return VirtualPathUtility.RemoveTrailingSlash(urlBuilder.ToString());
    }

    private static string tryCreateRelativeOrAbsolute(string s)
    {
        System.Uri uri;
        System.Uri.TryCreate(s, UriKind.RelativeOrAbsolute, out uri);
        string tempUrl = VirtualPathUtility.AppendTrailingSlash(uri.ToString());
        return tempUrl;
    }

完整的代码和单元测试可以在https://uricombine.codeplex.com/SourceControl/latest#UriCombine/Uri.cs

我有单元测试来涵盖三种最常见的情况:

Ryan Cook的答案与我的目标接近,可能更适合其他开发人员。然而,它在字符串的开头添加了http://,并且一般来说,它的格式比我想要的要多一些。

此外,对于我的用例,解析相对路径并不重要。

mdsharp的答案也包含了一个好主意的种子,尽管实际实现需要更多细节才能完成。这是一种充实它的尝试(我在生产中使用了这一点):

C#

public string UrlCombine(string url1, string url2)
{
    if (url1.Length == 0) {
        return url2;
    }

    if (url2.Length == 0) {
        return url1;
    }

    url1 = url1.TrimEnd('/', '\\');
    url2 = url2.TrimStart('/', '\\');

    return string.Format("{0}/{1}", url1, url2);
}

VB.NET

Public Function UrlCombine(ByVal url1 As String, ByVal url2 As String) As String
    If url1.Length = 0 Then
        Return url2
    End If

    If url2.Length = 0 Then
        Return url1
    End If

    url1 = url1.TrimEnd("/"c, "\"c)
    url2 = url2.TrimStart("/"c, "\"c)

    Return String.Format("{0}/{1}", url1, url2)
End Function

这段代码通过了以下测试,恰好是在VB中:

<TestMethod()> Public Sub UrlCombineTest()
    Dim target As StringHelpers = New StringHelpers()

    Assert.IsTrue(target.UrlCombine("test1", "test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("test1/", "test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("test1", "/test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("test1/", "/test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("/test1/", "/test2/") = "/test1/test2/")
    Assert.IsTrue(target.UrlCombine("", "/test2/") = "/test2/")
    Assert.IsTrue(target.UrlCombine("/test1/", "") = "/test1/")
End Sub

最近,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图库上的软件包

代码示例

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