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"
当前回答
这两种方法都有效:
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。