Объединение двух относительных юрис - PullRequest
11 голосов
/ 08 декабря 2010

Мне нужно объединить два относительных Uris, например, ../mypath/ и myimage.png для создания ../mypath/myimage.png. Они не являются путями к файлам на диске, поэтому Path.Combine не подходит (они являются относительными путями к ресурсам для веб-страницы). new Uri выдает ArgumentOutOfRangeException, потому что базовый URI является относительным (не абсолютным).

Есть ли у меня какие-либо варианты, кроме проверки на наличие косой черты и последующего объединения путей самостоятельно?

EDIT:

Вот тестовый пример, который демонстрирует, что 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);
}

Ответы [ 3 ]

8 голосов
/ 20 сентября 2012

Если ваша вторая часть (как в моем собственном случае) действительно является именем файла без экранирования (и поэтому может содержать символы инвалидности для URL-адреса), вот решение, которое я выбрал:

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

Помните, что это решение не будет поддерживать полный URI (со схемой, хостом, портом): оно выдаст исключение с полным URI.Спасибо Маниш Пансинии за упоминание 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 для .Select и fx4 для используемой строки. Перегрузка Join.)

4 голосов
/ 08 декабря 2010

Не используйте path.combine, так как он используется для физического пути, чтобы он мог сбить вас с толку.Вы можете сделать свою собственную функцию объединения Uri.Проверка слеша в конце и добавление к следующему.

Может ли конструктор URI с двумя аргументами помочь?

new Uri(Uri baseUri, string relativeUri)
3 голосов
/ 08 декабря 2010

Вы можете использовать конструктор Uri, который использует основание и относительную часть для выполнения комбинации - но учтите, что поведение, возможно, будет не тем, что вы ожидаете.Класс Uri будет видеть конечную часть вашей базы в виде «каталога» или «файла» (чтобы поместить его в термины пути).Если он видит конец как файл, он будет удален.

Например, сочетание http://server/something/ с resource.png даст вам http://server/something/resource.png.

Теперь опустите косую черту: объедините http://server/something с resource.png и получите http://server/resource.png.

Это имеет смысл, если вы думаете, что оно начинается с базового Uri http://server/something.pngи запрос относительного uri resource.png: http://server/something.png/resource.png - это не то, что вы ищете.

Если вы ВСЕГДА знаете, что они должны быть добавлены, вам нужно убедиться, что база заканчиваетсякосая черта перед объединением.

...