Path.Combine for URLs?
技术背景
在开发过程中,经常需要拼接URL的各个部分。然而,直接拼接可能会导致出现多余的斜杠或缺少必要的分隔符等问题。虽然Path.Combine
可用于拼接文件路径,但对于URL并不适用,因为URL可能包含特殊字符,且有自己的格式要求。因此,需要寻找合适的方法来正确拼接URL。
实现步骤
1. 使用Uri
构造函数
可以使用Uri
类的构造函数new Uri(Uri baseUri, string relativeUri)
来拼接URL。示例代码如下:
1 2
| Uri baseUri = new Uri("http://www.contoso.com"); Uri myUri = new Uri(baseUri, "catalog/shownew.htm");
|
2. 自定义拼接方法
可以编写自定义方法来拼接URL,确保只有一个分隔符。示例代码如下:
1 2 3 4 5 6
| public static string Combine(string uri1, string uri2) { uri1 = uri1.TrimEnd('/'); uri2 = uri2.TrimStart('/'); return string.Format("{0}/{1}", uri1, uri2); }
|
3. 使用扩展方法
可以创建扩展方法来处理Uri
实例。示例代码如下:
1 2 3 4 5 6 7 8 9 10
| using System; using System.Linq;
public static class UriExtensions { public static Uri Append(this Uri uri, params string[] paths) { return new Uri(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/')))); } }
|
使用示例:
1
| var url = new Uri("http://example.com/subpath/").Append("/part1/", "part2").AbsoluteUri;
|
4. 使用Flurl
库
Flurl
库提供了Url.Combine
方法,类似于Path.Combine
。示例代码如下:
1 2 3 4 5 6
| var url = Url.Combine( "http://MyUrl.com/", "/too/", "/many/", "/slashes/", "too", "few?", "x=1", "y=2" );
|
可以通过NuGet安装Flurl.Http
或Flurl
:
1 2
| PM> Install-Package Flurl.Http PM> Install-Package Flurl
|
5. 使用VirtualPathUtility.Combine
VirtualPathUtility.Combine
方法可用于拼接相对URL。示例代码如下:
1
| var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");
|
需要注意的是,该方法仅适用于相对URL。
6. 使用UriBuilder
可以使用UriBuilder
来构建URL。示例代码如下:
1 2 3 4 5 6 7 8 9
| public string CombineUrl(string baseUrl, string relativeUrl) { UriBuilder baseUri = new UriBuilder(baseUrl); Uri newUri;
if (Uri.TryCreate(baseUri.Uri, relativeUrl, out newUri)) return newUri.ToString(); else throw new ArgumentException("Unable to combine specified url values"); }
|
核心代码
以下是一些核心代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public static string Combine(string uri1, string uri2) { uri1 = uri1.TrimEnd('/'); uri2 = uri2.TrimStart('/'); return string.Format("{0}/{1}", uri1, uri2); }
public static class UriExtensions { public static Uri Append(this Uri uri, params string[] paths) { return new Uri(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/')))); } }
var url = Url.Combine( "http://MyUrl.com/", "/too/", "/many/", "/slashes/", "too", "few?", "x=1", "y=2" );
var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");
public string CombineUrl(string baseUrl, string relativeUrl) { UriBuilder baseUri = new UriBuilder(baseUrl); Uri newUri;
if (Uri.TryCreate(baseUri.Uri, relativeUrl, out newUri)) return newUri.ToString(); else throw new ArgumentException("Unable to combine specified url values"); }
|
最佳实践
- 使用合适的方法:根据具体需求选择合适的方法,如简单拼接可使用自定义方法,处理复杂URL可使用
Flurl
库。 - 测试代码:在使用新方法之前,编写测试用例确保代码的正确性。
- 避免硬编码:尽量避免在代码中硬编码URL,使用配置文件或常量来管理URL。
常见问题
1. Uri
构造函数可能会截断部分URL
在某些情况下,Uri
构造函数可能会截断部分URL。例如:
1
| new Uri(new Uri("http://www.mediawiki.org/wiki/"), "Special:SpecialPages")
|
会导致结果为Special:SpecialPages
,因为Special
后面的冒号表示协议。
2. Path.Combine
不适用于URL
Path.Combine
不适用于URL,因为URL可能包含特殊字符,如|
,会导致ArgumentException
。
3. VirtualPathUtility.Combine
仅适用于相对URL
VirtualPathUtility.Combine
仅适用于相对URL,不能用于生成指向其他网站的链接。