Path.Combine jest przydatny, ale czy istnieje podobna funkcja w .NET dla adresów URL ?
Szukam takiej składni:
Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")
który zwróciłby:
"http://MyUrl.com/Images/Image.jpg"
Path.Combine jest przydatny, ale czy istnieje podobna funkcja w .NET dla adresów URL ?
Szukam takiej składni:
Url.Combine("http://MyUrl.com/", "/Images/Image.jpg")
który zwróciłby:
"http://MyUrl.com/Images/Image.jpg"
Url.Combine
metodę, która właśnie to robi.Odpowiedzi:
Istnieje komentarz Todda Meniera powyżej, że Flurl zawiera
Url.Combine
.Więcej szczegółów:
Pobierz Flurl.Http na NuGet :
PM> Zainstaluj pakiet Flurl
Lub uzyskaj autonomiczny program do tworzenia adresów URL bez funkcji HTTP:
PM> Zainstaluj pakiet Flurl
źródło
Flurl
i korzystałbyś z lekkiej wersji, github.com/jean-lourenco/UrlCombineUri
ma konstruktor, który powinien to zrobić dla Ciebie:new Uri(Uri baseUri, string relativeUri)
Oto przykład:
Uwaga od edytora: Uwaga: ta metoda nie działa zgodnie z oczekiwaniami. W niektórych przypadkach może wyciąć część baseUri. Zobacz komentarze i inne odpowiedzi.
źródło
Może to być odpowiednio proste rozwiązanie:
źródło
Używasz
Uri.TryCreate( ... )
:Wróci:
źródło
int.TryParse
,DateTime.TryParseExact
) mają ten parametr wyjściowy, aby ułatwić korzystanie z nich w instrukcji if. Przy okazji, nie musisz inicjalizować zmiennej, jak Ryan w tym przykładzie.test.com/mydirectory/
i/helloworld.aspx
spowoduje, żetest.com/helloworld.aspx
pozornie nie jest to, czego chcesz.Tutaj jest już kilka świetnych odpowiedzi. W oparciu o sugestię mdsharpe, oto metoda rozszerzenia, której można łatwo użyć, gdy chcesz poradzić sobie z instancjami Uri:
I przykład użycia:
Spowoduje to utworzenie http://example.com/subpath/part1/part2
źródło
Odpowiedź Ryana Cooka jest zbliżona do tego, czego szukam i może być bardziej odpowiednia dla innych programistów. Dodaje jednak http: // na początku łańcucha i generalnie wykonuje nieco więcej formatowania niż ja.
Również w moich przypadkach użycia rozwiązywanie ścieżek względnych nie jest ważne.
Odpowiedź mdsharp zawiera również zalążek dobrego pomysłu, chociaż faktyczna implementacja wymagała jeszcze kilku szczegółów. To jest próba rozwinięcia go (i używam tego w produkcji):
DO#
VB.NET
Ten kod przechodzi następujący test, który zdarza się w VB:
źródło
ArgumentNullException("url1")
jeśli argument jestNothing
? Przepraszam, jestem wybredna ;-). Zwróć uwagę, że ukośnik odwrotny nie ma nic wspólnego z identyfikatorem URI (a jeśli już istnieje, nie należy go przycinać), więc możesz go usunąć z TrimXXX.Path.Combine nie działa dla mnie, ponieważ mogą istnieć znaki takie jak „|” w argumentach QueryString, a zatem adres URL, co spowoduje wyjątek ArgumentException.
Najpierw wypróbowałem nowe
Uri(Uri baseUri, string relativeUri)
podejście, które nie powiodło się z powodu URI takich jakhttp://www.mediawiki.org/wiki/Special:SpecialPages
:spowoduje utworzenie Special: SpecialPages, ponieważ dwukropek
Special
oznacza schemat.W końcu musiałem wybrać trasę mdsharpe / Brian MacKays i rozwinąłem ją nieco dalej, aby pracować z wieloma częściami URI:
Stosowanie:
CombineUri("http://www.mediawiki.org/", "wiki", "Special:SpecialPages")
źródło
Na podstawie podanego przez Ciebie przykładowego adresu URL założę, że chcesz łączyć adresy URL dotyczące Twojej witryny.
W oparciu o to założenie zaproponuję to rozwiązanie jako najbardziej odpowiednią odpowiedź na twoje pytanie, które brzmiało: „Path.Combine jest przydatny, czy istnieje podobna funkcja w ramach dla adresów URL?”
Ponieważ w strukturze URL istnieje podobna funkcja, proponuję poprawną metodę: „VirtualPathUtility.Combine”. Oto link referencyjny MSDN: Metoda VirtualPathUtility.Combine
Jest jedno zastrzeżenie: uważam, że działa to tylko w przypadku adresów URL związanych z witryną (tzn. Nie można jej używać do generowania linków do innej witryny. Na przykład
var url = VirtualPathUtility.Combine("www.google.com", "accounts/widgets");
).źródło
Server.MapPath
łączenia i łączenia.źródło
path.Replace(Path.DirectorySeparatorChar, '/');
path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
Właśnie stworzyłem małą metodę rozszerzenia:
Można go użyć w następujący sposób:
źródło
Dowcipny przykład, Ryan, kończący się linkiem do funkcji. Dobra robota.
Jedna rekomendacja Brian: jeśli zawiniesz ten kod w funkcji, możesz użyć UriBuilder do zawinięcia podstawowego adresu URL przed wywołaniem TryCreate.
W przeciwnym razie podstawowy adres URL MUSI zawierać schemat (gdzie UriBuilder przyjmie http: //). Tylko myśl:
źródło
Łatwy sposób na ich połączenie i upewnienie się, że zawsze jest poprawny, to:
źródło
Łączenie wielu części adresu URL może być nieco trudne. Możesz użyć konstruktora dwuparametrowego
Uri(baseUri, relativeUri)
lubUri.TryCreate()
funkcji narzędziowej.W obu przypadkach może skończyć się powrotem niepoprawny wynik, ponieważ metody te przechowywać na obcinanie części względne off z pierwszego parametru
baseUri
, czyli z czegoś podobnegohttp://google.com/some/thing
dohttp://google.com
.Aby połączyć wiele części w końcowy adres URL, możesz skopiować dwie funkcje poniżej:
Pełny kod z testami jednostkowymi w celu wykazania użycia można znaleźć na stronie https://uricombine.codeplex.com/SourceControl/latest#UriCombine/Uri.cs
Mam testy jednostkowe obejmujące trzy najczęstsze przypadki:
źródło
Uważam, że
UriBuilder
działa naprawdę dobrze w tego typu rzeczach:Zobacz Klasa UriBuilder - MSDN, aby uzyskać więcej konstruktorów i dokumentacji.
źródło
Oto metoda Microsoft (OfficeDev PnP) UrlUtility.Combine :
Źródło: GitHub
źródło
Uważam, że następujące przydatne i ma następujące funkcje:
params
parametrów dla wielu segmentów adresu URLKlasa
Testy
źródło
Moje ogólne rozwiązanie:
źródło
Stworzyłem tę funkcję, która ułatwi Ci życie:
Działa zarówno w przypadku adresów URL, jak i zwykłych ścieżek.
Stosowanie:
źródło
Dlaczego nie skorzystać z poniższych.
źródło
[System.IO.Path]::Combine("http://MyUrl.com/","/Images/Image.jpg")
Jednak to nie powiedzie się z powodu:/Images/Image.jpg
. Usuń/
drugą ścieżkę podrzędną i zadziała:[System.IO.Path]::Combine("http://MyUrl.com/","Images/Image.jpg")
Reguły podczas łączenia adresów URL z identyfikatorem URI
Aby uniknąć dziwnego zachowania, należy przestrzegać jednej zasady:
string.Empty
usuwane ... dodanie ścieżki części spowoduje usunięcie katalogu względnego z adresu URL!Jeśli przestrzegasz powyższych zasad, możesz łączyć adresy URL z poniższym kodem. W zależności od sytuacji możesz dodać wiele części katalogu do adresu URL ...
źródło
Jeśli nie chcesz dodawać zależności innej firmy, takiej jak Flurl, ani tworzyć niestandardowej metody rozszerzenia, w programie ASP.NET Core (dostępnym również w Microsoft.Owin), możesz użyć tego,
PathString
co jest przeznaczone do budowania identyfikatora URI ścieżki Następnie możesz utworzyć pełny identyfikator URI, używając kombinacji tegoUri
iUriBuilder
.W takim przypadku byłoby to:
To daje wszystkie części składowe bez konieczności określania separatorów w podstawowym adresie URL. Niestety,
PathString
wymaga, że/
jest dołączane do każdego łańcucha, w przeciwnym razie w rzeczywistości wyrzucaArgumentException
! Ale przynajmniej możesz zbudować swój URI deterministycznie w sposób, który można łatwo przetestować jednostkowo.źródło
Mam więc inne podejście, podobne do wszystkich, którzy korzystali z UriBuilder.
Nie chciałem podzielić moją baseURL (który może zawierać część ścieżki - np http://mybaseurl.com/dev/ ) jako javajavajavajavajava zrobił.
Poniższy fragment kodu pokazuje kod + testy.
Uwaga: to rozwiązanie obniża liczbę hostów i dodaje port. Jeśli nie jest to pożądane, można napisać ciąg znaków, np. Wykorzystując
Uri
właściwośćUriBuilder
.Testowane z .NET Core 2.1 w systemie Windows 10.
Dlaczego to działa?
Mimo że
Path.Combine
zwróci ukośniki odwrotne (przynajmniej w systemie Windows), UriBuilder obsługuje tę sprawę w SetterzePath
.Zaczerpnięte z https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/src/System/UriBuilder.cs (pamiętaj o wezwaniu do
string.Replace
)Czy to najlepsze podejście?
Z pewnością to rozwiązanie jest dość samoopisujące (przynajmniej moim zdaniem). Ale polegasz na nieudokumentowanej (przynajmniej nie znalazłem nic dzięki szybkiemu wyszukiwaniu w Google) „funkcji” interfejsu API .NET. Może to ulec zmianie w przyszłej wersji, dlatego prosimy o objęcie metody testami.
Istnieją testy w https://github.com/dotnet/corefx/blob/master/src/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs (
Path_Get_Set
), które sprawdzają, czy dane\
są poprawnie przekształcone.Uwaga dodatkowa: Można również pracować
UriBuilder.Uri
bezpośrednio z właściwością, jeśli identyfikatorSystem.Uri
URI zostanie użyty dla ctor.źródło
Dla każdego, kto szuka jednej linijki i po prostu chce połączyć części ścieżki bez tworzenia nowej metody lub odwoływania się do nowej biblioteki lub konstruowania wartości URI i konwertowania jej na ciąg, a następnie ...
To dość proste, ale nie widzę, czego więcej potrzebujesz. Jeśli boisz się podwojonego „/”, możesz po prostu zrobić
.Replace("//", "/")
później. Jeśli boisz się zastąpić podwójny „//” w „https: //”, to zamiast tego wykonaj jedno łączenie, zamień podwójne „/”, a następnie dołącz do adresu URL witryny (jednak jestem prawie pewien, że większość przeglądarek automatycznie przekonwertować wszystko za pomocą „https:” z przodu, aby odczytać w odpowiednim formacie). Wyglądałoby to tak:Istnieje wiele odpowiedzi, które poradzą sobie z powyższymi, ale w moim przypadku potrzebowałem go tylko raz w jednym miejscu i nie będę musiał na nim polegać. Ponadto bardzo łatwo jest zobaczyć, co się tutaj dzieje.
Zobacz: https://docs.microsoft.com/en-us/dotnet/api/system.string.join?view=netframework-4.8
źródło
Posługiwać się:
Ma tę zaletę, że zachowuje się dokładnie tak samo
Path.Combine
.źródło
Oto moje podejście i wykorzystam je również dla siebie:
źródło
Użyj tego:
źródło
Odkryłem, że
Uri
konstruktor zamienia „\” na „/”. Możesz więc użyć równieżPath.Combine
zUri
konstruktorem.źródło
Dla tego, co warto, oto kilka metod rozszerzenia. Pierwszy połączy ścieżki, a drugi doda parametry do adresu URL.
źródło
Jak stwierdzono w innych odpowiedziach, albo nowe,
Uri()
alboTryCreate()
można zrobić tyknięcie. Jednak podstawowy Uri musi się kończyć,/
a krewny NIE musi zaczynać/
; w przeciwnym razie usunie końcową część podstawowego adresu URLMyślę, że najlepiej to zrobić jako metodę rozszerzenia, tj
i użyć go:
Pod względem wydajności zużywa więcej zasobów, niż potrzebuje, ze względu na klasę Uri, która wykonuje wiele analiz i weryfikacji; bardzo zgrubne profilowanie (Debugowanie) wykonało milion operacji w około 2 sekundy. Będzie to działać w większości scenariuszy, jednak aby być bardziej wydajnym, lepiej manipulować wszystkim jako ciągami, zajmuje to 125 milisekund na 1 milion operacji. To znaczy
A jeśli nadal chcesz zwrócić identyfikator URI, zajmuje to około 600 milisekund na 1 milion operacji.
Mam nadzieję, że to pomoże.
źródło
Myślę, że powinno to zapewnić większą elastyczność, ponieważ możesz poradzić sobie z tyloma segmentami ścieżki, ile chcesz:
źródło