我需要结合两个相对的Uris,例如../mypath/
和myimage.png
创建../mypath/myimage.png
。它们不是磁盘上文件的路径,因此Path.Combine
不合适(它们是网页资源的相对路径)。 new Uri
会抛出ArgumentOutOfRangeException
,因为基础uri是相对的(不是绝对的)。
除了检查尾部斜杠然后自己组合路径之外,我还有其他选择吗?
编辑:
这是一个测试用例,它表明Path.Combine不适用于第一个url尚未包含尾部斜杠的情况:
// The first case fails with result "../testpath\resource.png"
[TestCase("../testpath", "resource.png", "../testpath/resource.png")]
[TestCase("../testpath/", "resource.png", "../testpath/resource.png")]
public void TestPathCombine(string path, string resourceName, string expectedResult) {
string result = Path.Combine(path, resourceName);
Assert.AreEqual(expectedResult, result);
}
答案 0 :(得分:8)
如果你的第二部分(就像我自己的情况一样)真的是一个没有任何转义的文件名(因此可能包含一个url的invalids字符),这里是我最终得到的解决方案:
VirtualPathUtility.Combine(
VirtualPathUtility.AppendTrailingSlash(relativeUri),
Uri.EscapeDataString(fileName));
请注意,此解决方案不支持完整的uri(带有方案,主机,端口):它将使用完整的uri抛出异常。 感谢Manish Pansiniya mentioning System.Web.VirtualPathUtility。
另外,由于我的文件名实际上是部分文件路径(某些文件夹名称后跟文件名),而不是直接调用System.Uri.EscapeDataString,我调用了以下函数:
/// <summary>
/// Convert a partial file path to a partial url path.
/// </summary>
/// <param name="partialFilePath">The partial file path.</param>
/// <returns>A partial url path.</returns>
public static string ConvertPartialFilePathToPartialUrlPath(
string partialFilePath)
{
if (partialFilePath == null)
return null;
return string.Join("/",
partialFilePath.Split('/', '\\')
.Select(part => Uri.EscapeDataString(part)));
}
(对于使用过的string.Join重载,需要使用System.Linq for .Select和fx4。)
答案 1 :(得分:4)
请勿使用path.combine作为物理路径,因此可能会将您与斜线混淆。你可以把你自己的Uri功能结合起来。检查结尾处的斜线并将其附加到下一个斜杠。
有两个参数的URI构造函数可以帮助吗?
new Uri(Uri baseUri, string relativeUri)
答案 2 :(得分:3)
您可以使用带有基数和相对部分的Uri
构造函数来进行组合 - 但请注意,行为可能不是您所期望的。 Uri
类将基本的末尾部分视为“目录”或“文件”(以路径术语表示)。如果它将结束视为文件,则会将其删除。
例如,将http://server/something/
与resource.png
合并将为您提供http://server/something/resource.png
。
现在省略尾部斜杠:将http://server/something
与resource.png
合并,然后获取http://server/resource.png
。
如果你认为它是以http://server/something.png
的基础Uri开头并且要求相对的uri resource.png
,那么这是有道理的:http://server/something.png/resource.png
不是你想要的。
如果您始终知道应该追加它们,则需要确保在合并之前基础以斜线结尾。