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"
当前回答
组合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
我有单元测试来涵盖三种最常见的情况:
其他回答
我认为这应该给你更多的灵活性,因为你可以处理任意多的路径段:
public static string UrlCombine(this string baseUrl, params string[] segments)
=> string.Join("/", new[] { baseUrl.TrimEnd('/') }.Concat(segments.Select(s => s.Trim('/'))));
我必须指出,Path.Combine似乎也能直接实现这一点,至少在.NET 4上是如此。
根据您提供的示例URL,我将假设您希望组合与站点相关的URL。
基于这一假设,我将提出这个解决方案,作为对您的问题的最恰当的回答:“Path.Combine很方便,在URL框架中有类似的功能吗?”
由于URL框架中有一个类似的函数,我建议正确的方法是:“VirtualPathUtility.Compine”方法。下面是MSDN参考链接:VirtualPathUtility.Combine方法
有一个警告:我认为这只适用于与您的网站相关的url(即,您不能使用它来生成指向另一个网站的链接。例如,var url=VirtualPathUtility.Combine(“www.google.com”,“accounts/widgets”);)。
正如在其他答案中发现的那样,newUri()或TryCreate()都可以完成勾选。但是,基Uri必须以/结尾,而相对Uri必须不以/开头;否则它将删除基Url的尾部
我认为这是最好的扩展方法,即。
public static Uri Append(this Uri uri, string relativePath)
{
var baseUri = uri.AbsoluteUri.EndsWith('/') ? uri : new Uri(uri.AbsoluteUri + '/');
var relative = relativePath.StartsWith('/') ? relativePath.Substring(1) : relativePath;
return new Uri(baseUri, relative);
}
并使用它:
var baseUri = new Uri("http://test.com/test/");
var combinedUri = baseUri.Append("/Do/Something");
就性能而言,这消耗了比所需更多的资源,因为Uri类需要进行大量的分析和验证;一个非常粗略的评测(Debug)在大约2秒内完成了一百万次操作。这将适用于大多数场景,但为了更高效,最好将所有内容都作为字符串进行操作,这需要125毫秒才能完成100万次操作。即。
public static string Append(this Uri uri, string relativePath)
{
//avoid the use of Uri as it's not needed, and adds a bit of overhead.
var absoluteUri = uri.AbsoluteUri; //a calculated property, better cache it
var baseUri = absoluteUri.EndsWith('/') ? absoluteUri : absoluteUri + '/';
var relative = relativePath.StartsWith('/') ? relativePath.Substring(1) : relativePath;
return baseUri + relative;
}
如果您仍然希望返回URI,那么100万次操作需要大约600毫秒。
public static Uri AppendUri(this Uri uri, string relativePath)
{
//avoid the use of Uri as it's not needed, and adds a bit of overhead.
var absoluteUri = uri.AbsoluteUri; //a calculated property, better cache it
var baseUri = absoluteUri.EndsWith('/') ? absoluteUri : absoluteUri + '/';
var relative = relativePath.StartsWith('/') ? relativePath.Substring(1) : relativePath;
return new Uri(baseUri + relative);
}
我希望这有帮助。
如果您不想在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。