Path.Combine很方便,但是.NET框架中是否有类似的URL函数?
我正在寻找这样的语法:
Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")
这将返回:
"http://MyUrl.com/Images/Image.jpg"
Path.Combine很方便,但是.NET框架中是否有类似的URL函数?
我正在寻找这样的语法:
Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")
这将返回:
"http://MyUrl.com/Images/Image.jpg"
当前回答
如果您不想在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。
其他回答
Path.Combine对我不起作用,因为QueryString参数中可能有“|”这样的字符,因此URL也会出现ArgumentException。
我首先尝试了新的Uri(Uri-baseUri,string relativeUri)方法,但由于以下Uri而失败http://www.mediawiki.org/wiki/Special:SpecialPages:
new Uri(new Uri("http://www.mediawiki.org/wiki/"), "Special:SpecialPages")
将导致Special:SpecialPages,因为Special后面的冒号表示方案。
因此,我最终不得不采用mdsharpe/Brian MacKays路线,并进一步开发它,以处理多个URI部分:
public static string CombineUri(params string[] uriParts)
{
string uri = string.Empty;
if (uriParts != null && uriParts.Length > 0)
{
char[] trims = new char[] { '\\', '/' };
uri = (uriParts[0] ?? string.Empty).TrimEnd(trims);
for (int i = 1; i < uriParts.Length; i++)
{
uri = string.Format("{0}/{1}", uri.TrimEnd(trims), (uriParts[i] ?? string.Empty).TrimStart(trims));
}
}
return uri;
}
用法:CombineUri(“http://www.mediawiki.org/“,”wiki“,”Special:SpecialPages“)
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
为什么不使用以下选项。
System.IO.Path.Combine(rootUrl, subPath).Replace(@"\", "/")
上面有托德·梅尼尔(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有一个构造函数可以为您执行此操作:new Uri(Uri baseUri,string relativeUri)
下面是一个示例:
Uri baseUri = new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm");
编辑注意:小心,这种方法并不能像预期的那样工作。在某些情况下,它可以剪切baseUri的一部分。查看评论和其他答案。