问题 结合两个相对的Uris


我需要结合两个相对的Uris,例如 ../mypath/ 和 myimage.png 创造 ../mypath/myimage.png。它们不是磁盘上文件的路径 Path.Combine 是不合适的(它们是网页资源的相对路径)。 new Uri 抛出一个 ArgumentOutOfRangeException 因为基础uri是相对的(不是绝对的)。

除了检查尾部斜线然后自己组合路径之外,我还有其他选择吗?

编辑:

这是一个测试用例,它表明当第一个url尚未包含尾部斜杠时,Path.Combine不适用于这种情况:

// 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);
}

8238
2017-12-08 17:59


起源

可能重复 将相对baseUri与相对路径相结合 - Joey Adams


答案:


不要像使用物理路径那样使用path.combine,因此可能会使用斜线来混淆。你可以把你自己的Uri功能组合起来。检查结尾处的斜杠并将其附加到下一个斜杠。

可以用两个参数的URI构造函数帮助吗?

new Uri(Uri baseUri, string relativeUri)

4
2017-12-08 18:37



正如我在帖子中所说的那样,新的URI构造函数失败了 ArgumentOutOfRangeException 因为baseUri是相对的。创建我自己的功能似乎是我唯一的选择。 - Lawrence Johnston
我认为这是最好的方法。借助VirtualPathUtility类。它具有组合功能,但我不确定它是否完全符合您的要求。但它具有可能有助于制作一个功能的功能。例如AppendTrailingSlash和AppendTrailingSlash - Manish Pansiniya
VirtualPathUtility.AppendTrailingSlash加上简单的字符串连接解决了这个问题。但是最后我决定要求并记录首先需要基本路径的斜杠。 - Lawrence Johnston
伟大的劳伦斯。如果您编辑帖子并将功能放在此处会很有用,因为它可能会帮助访问此帖子的人:P - Manish Pansiniya


如果你的第二部分(就像在我自己​​的情况下)真的是一个没有任何转义的文件名(因此可能包含一个url的invalids字符),这里是我最终得到的解决方案:

VirtualPathUtility.Combine(
    VirtualPathUtility.AppendTrailingSlash(relativeUri), 
    Uri.EscapeDataString(fileName));

请注意,此解决方案不支持完整的uri(使用方案,主机,端口):它将使用完整的uri抛出异常。 感谢Manish Pansiniya 提到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)));
}

(需要使用System.Linq for .Select和fx4使用的string.Join重载。)


8
2017-09-20 18:12





你可以使用 Uri 采用基数和相对部分进行组合的构造函数 - 但请注意,行为可能不是您所期望的。该 Uri class会将基数的末尾部分视为“目录”或“文件”(以路径术语表示)。如果它将结束视为文件,则会将其删除。

例如,合并 http://server/something/ 同 resource.png 会给你 http://server/something/resource.png

现在省略尾部斜杠:combine http://server/something 同 resource.png 得到 http://server/resource.png

如果你认为它是从基础Uri开始的话,这是有道理的 http://server/something.png 并要求相对uri resource.pnghttp://server/something.png/resource.png 不是你想要的。

如果您始终知道应该追加它们,则需要确保在组合之前基础以斜线结尾。


3
2017-12-08 18:55