Path.Combine для URL? - PullRequest
       125

Path.Combine для URL?

1134 голосов
/ 17 декабря 2008

Path.Combine удобен, но есть ли аналогичная функция в .NET Framework для URLs ?

Я ищу следующий синтаксис:

Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")

, который вернется:

"http://MyUrl.com/Images/Image.jpg"

Ответы [ 33 ]

1090 голосов
/ 06 октября 2009

Uri имеет конструктор, который должен сделать это за вас: new Uri(Uri baseUri, string relativeUri)

Вот пример:

Uri baseUri = new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm");

Примечание редактора: будьте осторожны, этот метод не работает должным образом. В некоторых случаях он может вырезать часть baseUri. Смотрите комментарии и другие ответы.

139 голосов
/ 17 декабря 2008

Вы используете Uri.TryCreate( ... ):

Uri result = null;

if (Uri.TryCreate(new Uri("http://msdn.microsoft.com/en-us/library/"), "/en-us/library/system.uri.trycreate.aspx", out result))
{
    Console.WriteLine(result);
}

Вернется:

http://msdn.microsoft.com/en-us/library/system.uri.trycreate.aspx

133 голосов
/ 25 сентября 2009

Это может быть достаточно простое решение:

public static string Combine(string uri1, string uri2)
{
    uri1 = uri1.TrimEnd('/');
    uri2 = uri2.TrimStart('/');
    return string.Format("{0}/{1}", uri1, uri2);
}
117 голосов
/ 03 ноября 2011

Здесь уже есть несколько отличных ответов. Основываясь на предложении mdsharpe, вот метод расширения, который можно легко использовать, когда вы хотите работать с экземплярами Uri:

using System;
using System.Linq;

public static class UriExtensions
{
    public static Uri Append(this Uri uri, params string[] paths)
    {
        return new Uri(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
    }
}

И пример использования:

var url = new Uri("http://example.com/subpath/").Append("/part1/", "part2").AbsoluteUri;

Это даст http://example.com/subpath/part1/part2

82 голосов
/ 11 мая 2010

Ответ Райана Кука близок к тому, что мне нужно, и может быть более подходящим для других разработчиков. Тем не менее, он добавляет http: // в начало строки и, в общем, форматирует немного больше, чем я.

Кроме того, для моих случаев использования определение относительных путей не важно.

Ответ mdsharp также содержит в себе начало хорошей идеи, хотя для фактической реализации потребовалось еще несколько подробностей для завершения. Это попытка уточнить это (и я использую это в производстве):

C #

public string UrlCombine(string url1, string url2)
{
    if (url1.Length == 0) {
        return url2;
    }

    if (url2.Length == 0) {
        return url1;
    }

    url1 = url1.TrimEnd('/', '\\');
    url2 = url2.TrimStart('/', '\\');

    return string.Format("{0}/{1}", url1, url2);
}

VB.NET

Public Function UrlCombine(ByVal url1 As String, ByVal url2 As String) As String
    If url1.Length = 0 Then
        Return url2
    End If

    If url2.Length = 0 Then
        Return url1
    End If

    url1 = url1.TrimEnd("/"c, "\"c)
    url2 = url2.TrimStart("/"c, "\"c)

    Return String.Format("{0}/{1}", url1, url2)
End Function

Этот код проходит следующий тест, который происходит в VB:

<TestMethod()> Public Sub UrlCombineTest()
    Dim target As StringHelpers = New StringHelpers()

    Assert.IsTrue(target.UrlCombine("test1", "test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("test1/", "test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("test1", "/test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("test1/", "/test2") = "test1/test2")
    Assert.IsTrue(target.UrlCombine("/test1/", "/test2/") = "/test1/test2/")
    Assert.IsTrue(target.UrlCombine("", "/test2/") = "/test2/")
    Assert.IsTrue(target.UrlCombine("/test1/", "") = "/test1/")
End Sub
33 голосов
/ 28 марта 2010

На основе предоставленного вами образца URL я предполагаю, что вы хотите объединить URL-адреса, относящиеся к вашему сайту.

Исходя из этого предположения, я предложу это решение как наиболее подходящий ответ на ваш вопрос: «Path.Combine удобен, есть ли подобная функция в рамки для URL? "

Поскольку в структуре для URL-адресов есть аналогичная функция , я предлагаю правильный метод: VirtualPathUtility.Combine. Вот ссылка на MSDN: VirtualPathUtility.Combine Method

Существует одно предупреждение: я считаю, что это работает только для URL, относящихся к вашему сайту (то есть вы не можете использовать его для создания ссылок на другой веб-сайт. Например, var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");).

29 голосов
/ 15 июля 2011

Path.Combine не работает для меня, потому что могут быть такие символы, как "|" в аргументах QueryString и, следовательно, в URL, что приведет к исключению ArgumentException.

Я впервые попробовал новый подход Uri(Uri baseUri, string relativeUri), который мне не удался из-за URI, таких как http://www.mediawiki.org/wiki/Special:SpecialPages:

new Uri(new Uri("http://www.mediawiki.org/wiki/"), "Special:SpecialPages")

приведет к Special: SpecialPages из-за двоеточия после Special, обозначающего схему.

Итак, мне, наконец, пришлось выбрать маршрут mdsharpe / Brian MacKays, и я разработал его немного дальше для работы с несколькими частями URI:

public static string CombineUri(params string[] uriParts)
{
    string uri = string.Empty;
    if (uriParts != null && uriParts.Length > 0)
    {
        char[] trims = new char[] { '\\', '/' };
        uri = (uriParts[0] ?? string.Empty).TrimEnd(trims);
        for (int i = 1; i < uriParts.Length; i++)
        {
            uri = string.Format("{0}/{1}", uri.TrimEnd(trims), (uriParts[i] ?? string.Empty).TrimStart(trims));
        }
    }
    return uri;
}

Использование: CombineUri("http://www.mediawiki.org/", "wiki", "Special:SpecialPages")

25 голосов
/ 13 апреля 2018

Там есть комментарий Тодда Меньера выше , что Flurl включает Url.Combine.

Подробнее:

Url.Combine - это, по сути, Path.Combine для URL, обеспечивающий и только один символ разделителя между частями:

var url = Url.Combine(
    "http://foo.com/",
    "/too/", "/many/", "/slashes/",
    "too", "few?",
    "x=1", "y=2"
// result: "http://www.foo.com/too/many/slashes/too/few?x=1&y=2" 

Получить Flurl.Http на NuGet :

PM> Install-Package Flurl.Http

или получить автономный конструктор URL без функций HTTP:

PM> Установка пакета Flurl

23 голосов
/ 12 января 2011
Path.Combine("Http://MyUrl.com/", "/Images/Image.jpg").Replace("\\", "/")
16 голосов
/ 25 ноября 2010

Я просто собрал небольшой метод расширения:

public static string UriCombine (this string val, string append)
        {
            if (String.IsNullOrEmpty(val)) return append;
            if (String.IsNullOrEmpty(append)) return val;
            return val.TrimEnd('/') + "/" + append.TrimStart('/');
        }

Может использоваться следующим образом:

"www.example.com/".UriCombine("/images").UriCombine("first.jpeg");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...