System.Uri, klasa

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Identyfikator URI to kompaktowa reprezentacja zasobu dostępnego dla aplikacji w intranecie lub Internecie. Klasa Uri definiuje właściwości i metody obsługi identyfikatorów URI, w tym analizowanie, porównywanie i łączenie. Uri Właściwości klasy są tylko do odczytu; aby utworzyć obiekt modyfikowalny, użyj UriBuilder klasy .

Względne identyfikatory URI (na przykład "/new/index.htm") muszą być rozwinięte w odniesieniu do podstawowego identyfikatora URI, aby były bezwzględne. Metoda MakeRelativeUri jest udostępniana w celu przekonwertowania bezwzględnych identyfikatorów URI na względne identyfikatory URI w razie potrzeby.

Konstruktory Uri nie unikną ciągów identyfikatora URI, jeśli ciąg jest dobrze sformułowanym identyfikatorem URI, w tym identyfikatorem schematu.

Właściwości Uri zwracają kanoniczną reprezentację danych w kodowaniu ucieczki, a wszystkie znaki z wartościami Unicode większymi niż 127 zastąpione ich odpowiednikami szesnastkowymi. Aby umieścić identyfikator URI w postaci kanonicznej, Uri konstruktor wykonuje następujące kroki:

  • Konwertuje schemat identyfikatora URI na małe litery.

  • Konwertuje nazwę hosta na małe litery.

  • Jeśli nazwa hosta jest adresem IPv6, używany jest kanoniczny adres IPv6. Identyfikator scopeId i inne opcjonalne dane IPv6 są usuwane.

  • Usuwa domyślne i puste numery portów.

  • Konwertuje niejawne ścieżki plików bez schematu file:// (na przykład "C:\my\file") na jawne ścieżki plików ze schematem file://.

  • Znaki ucieczki (znane również jako oktety zakodowane w procentach), które nie mają zarezerwowanego celu, są dekodowane (nazywane również unescaped). Te znaki bez zastrzeżeń obejmują wielkie i małe litery (%41-%5A i %61-%7A), cyfry dziesiętne (%30–%39), łącznik (%2D), kropkę (%2E), podkreślenie (%5F) i tyldę (%7E).

  • Canonicalizuje ścieżkę dla hierarchicznych identyfikatorów URI przez kompaktowanie sekwencji, takich jak /./, /.. /, i // (czy sekwencja jest uniknięta). Należy pamiętać, że istnieją pewne schematy, dla których te sekwencje nie są kompaktowane.

  • W przypadku hierarchicznych identyfikatorów URI, jeśli host nie zostanie zakończony ukośnikiem (/), zostanie dodany.

  • Domyślnie wszelkie zastrzeżone znaki w identyfikatorze URI są ucieczki zgodnie z RFC 2396. To zachowanie zmienia się, jeśli włączono analizowanie międzynarodowych identyfikatorów zasobów lub nazw domen międzynarodowych, w takim przypadku znaki zarezerwowane w identyfikatorze URI są usuwane zgodnie z RFC 3986 i RFC 3987.

W ramach kanonizacji w konstruktorze dla niektórych schematów, segmenty kropkowe i puste segmenty (, /../, i //) są kompaktowane (/./innymi słowy, są usuwane). Schematy, dla których Uri segmenty kompaktowania obejmują http, https, tcp, net.pipe i net.tcp. W przypadku niektórych innych schematów te sekwencje nie są kompaktowane. Poniższy fragment kodu pokazuje, jak kompaktowanie wygląda w praktyce. Sekwencje ucieczki są niewyobrażalne, jeśli to konieczne, a następnie kompaktowane.

var uri = new Uri("http://myUrl/../.."); // http scheme, unescaped
OR
var uri = new Uri("http://myUrl/%2E%2E/%2E%2E"); // http scheme, escaped
OR
var uri = new Uri("ftp://myUrl/../.."); // ftp scheme, unescaped
OR
var uri = new Uri("ftp://myUrl/%2E%2E/%2E%2E"); // ftp scheme, escaped

Console.WriteLine($"AbsoluteUri: {uri.AbsoluteUri}");
Console.WriteLine($"PathAndQuery: {uri.PathAndQuery}");

Po wykonaniu tego kodu zwraca dane wyjściowe podobne do poniższego tekstu.

AbsoluteUri: http://myurl/
PathAndQuery: /

Zawartość klasy można przekształcić Uri z odwołania identyfikatora URI kodowanego przez ucieczkę do czytelnego odwołania do identyfikatora ToString URI przy użyciu metody . Należy pamiętać, że niektóre zastrzeżone znaki mogą być nadal ucieczki w danych wyjściowych ToString metody . Ma to na celu obsługę jednoznacznej rekonstrukcji identyfikatora URI z wartości zwracanej przez ToString.

Niektóre identyfikatory URI zawierają identyfikator fragmentu lub zapytanie lub oba te identyfikatory. Identyfikator fragmentu to dowolny tekst, który jest zgodny z znakiem numeru (#), a nie zawierającym znaku numeru; tekst fragmentu jest przechowywany we Fragment właściwości . Informacje o kwerendzie to dowolny tekst, który jest zgodny z znakiem zapytania (?) w identyfikatorze URI; tekst zapytania jest przechowywany we Query właściwości .

Uwaga

Klasa URI obsługuje użycie adresów IP w obu czworokątach dla protokołu IPv4 i dwukropka szesnastkowa dla protokołu IPv6. Pamiętaj, aby ująć adres IPv6 w nawiasy kwadratowe, jak w http://[::1].

Obsługa międzynarodowego identyfikatora zasobów

Adresy internetowe są zwykle wyrażane przy użyciu jednolitych identyfikatorów zasobów, które składają się z bardzo ograniczonego zestawu znaków:

  • Wielkie i małe litery ASCII z alfabetu angielskiego.
  • Cyfry z zakresu od 0 do 9.
  • Niewielka liczba innych symboli ASCII.

Specyfikacje identyfikatorów URI są udokumentowane w dokumencie RFC 2396, RFC 2732, RFC 3986 i RFC 3987 opublikowanym przez Internet Engineering Task Force (IETF).

Identyfikatory, które ułatwiają identyfikowanie zasobów przy użyciu języków innych niż angielski i zezwalają na znaki inne niż ASCII (znaki w zestawie znaków Unicode/ISO 10646) są nazywane międzynarodowymi identyfikatorami zasobów (IRI). Specyfikacje dla środowisk IRI są udokumentowane w dokumencie RFC 3987 opublikowanym przez IETF. Używanie interfejsów IRI umożliwia adresowi URL zawieranie znaków Unicode.

W programie .NET Framework 4.5 lub nowszym interfejs IRI jest zawsze włączony i nie można go zmienić przy użyciu opcji konfiguracji. Możesz ustawić opcję konfiguracji w pliku machine.config lub w pliku app.config , aby określić, czy chcesz, aby międzynarodowe analizowanie nazwy domeny (IDN) było stosowane do nazwy domeny. Na przykład:

<configuration>
  <uri>
    <idn enabled="All" />
  </uri>
</configuration>

Włączenie nazwy IDN konwertuje wszystkie etykiety Unicode w nazwie domeny na ich odpowiedniki Punycode. Nazwy punycode zawierają tylko znaki ASCII i zawsze zaczynają się od prefiksu xn-. Powodem jest obsługa istniejących serwerów DNS w Internecie, ponieważ większość serwerów DNS obsługuje tylko znaki ASCII (zobacz RFC 3940).

Włączenie nazwy IDN wpływa na wartość Uri.DnsSafeHost właściwości. Włączenie sieci IDN może również zmienić zachowanie Equalsmetod , , OriginalStringGetComponentsi IsWellFormedOriginalString .

Istnieją trzy możliwe wartości dla nazwy IDN w zależności od używanych serwerów DNS:

  • włączona nazwa idn = wszystkie

    Ta wartość spowoduje przekonwertowanie nazw domen Unicode na ich odpowiedniki Punycode (nazwy IDN).

  • idn enabled = AllExceptIntranet

    Ta wartość spowoduje przekonwertowanie wszystkich nazw domen Unicode nie w lokalnym intranecie w celu użycia odpowiedników punycode (nazw IDN). W takim przypadku do obsługi nazw międzynarodowych w lokalnym intranecie serwery DNS używane dla intranetu powinny obsługiwać rozpoznawanie nazw Unicode.

  • włączona nazwa idn = Brak

    Ta wartość nie przekonwertuje żadnych nazw domen Unicode na używanie programu Punycode. Jest to wartość domyślna.

Normalizacja i sprawdzanie znaków są wykonywane zgodnie z najnowszymi regułami IRI w RFC 3986 i RFC 3987.

Przetwarzanie IRI i IDN w Uri klasie może być również kontrolowane przy użyciu System.Configuration.IriParsingElementklas ustawień , System.Configuration.IdnElementi System.Configuration.UriSection konfiguracji. Ustawienie System.Configuration.IriParsingElement włącza lub wyłącza przetwarzanie IRI w Uri klasie. Ustawienie System.Configuration.IdnElement włącza lub wyłącza przetwarzanie IDN w Uri klasie.

Ustawienie konfiguracji elementu System.Configuration.IriParsingElement i System.Configuration.IdnElement jest odczytywane raz po utworzeniu pierwszej System.Uri klasy. Zmiany ustawień konfiguracji po tym czasie są ignorowane.

Klasa System.GenericUriParser została również rozszerzona, aby umożliwić tworzenie dostosowywalnego analizatora obsługującego IRI i IDN. Zachowanie System.GenericUriParser obiektu jest określane przez przekazanie bitowej kombinacji wartości dostępnych w wyliczenie System.GenericUriParserOptions do konstruktora System.GenericUriParser . Typ GenericUriParserOptions.IriParsing wskazuje analizator obsługuje reguły analizowania określone w specyfikacji RFC 3987 dla międzynarodowych identyfikatorów zasobów (IRI).

Typ GenericUriParserOptions.Idn wskazuje, że analizator obsługuje analizowanie nazw hostów pod nazwą IDN (Internationalized Domain Name). W wersjach .NET 5 i nowszych (w tym .NET Core) i .NET Framework 4.5+, zawsze jest używana sieć IDN. W poprzednich wersjach opcja konfiguracji określa, czy jest używana sieci IDN.

Obsługa niejawnej ścieżki pliku

Uri można również użyć do reprezentowania lokalnych ścieżek systemu plików. Te ścieżki mogą być reprezentowane jawnie w identyfikatorach URI rozpoczynających się od schematu file:// i niejawnie w identyfikatorach URI, które nie mają schematu file://. W konkretnym przykładzie dwa następujące identyfikatory URI są prawidłowe i reprezentują tę samą ścieżkę pliku:

Uri uri1 = new Uri("C:/test/path/file.txt") // Implicit file path.
Uri uri2 = new Uri("file:///C:/test/path/file.txt") // Explicit file path.

Te niejawne ścieżki plików nie są zgodne ze specyfikacją identyfikatora URI, dlatego należy unikać ich, jeśli jest to możliwe. W przypadku korzystania z platformy .NET Core w systemach opartych na systemie Unix niejawne ścieżki plików mogą być szczególnie problematyczne, ponieważ bezwzględna niejawna ścieżka pliku jest nie do odróżnienia od ścieżki względnej. Gdy taka niejednoznaczność jest obecna, Uri domyślną wartością jest interpretowanie ścieżki jako bezwzględnego identyfikatora URI.

Zagadnienia dotyczące zabezpieczeń

Ze względu na obawy dotyczące zabezpieczeń aplikacja powinna zachować ostrożność podczas akceptowania Uri wystąpień z niezaufanych źródeł i z ustawioną wartością truedontEscape w konstruktorze. Możesz sprawdzić ciąg identyfikatora URI pod kątem ważności, wywołując metodę IsWellFormedOriginalString .

W przypadku czynienia z niezaufanymi danymi wejściowymi użytkownika potwierdź założenia dotyczące nowo utworzonego Uri wystąpienia przed zaufaniem do jego właściwości. Można to zrobić w następujący sposób:

string userInput = ...;

Uri baseUri = new Uri("https://myWebsite/files/");

if (!Uri.TryCreate(baseUri, userInput, out Uri newUri))
{
    // Fail: invalid input.
}

if (!baseUri.IsBaseOf(newUri))
{
    // Fail: the Uri base has been modified - the created Uri is not rooted in the original directory.
}

Tej weryfikacji można używać w innych przypadkach, takich jak podczas pracy ze ścieżkami UNC, zmieniając po prostu element baseUri:

Uri baseUri = new Uri(@"\\host\share\some\directory\name\");

Zagadnienia dotyczące wydajności

Jeśli używasz pliku Web.configzawierającego identyfikatory URI, aby zainicjować aplikację, wymagany jest dodatkowy czas na przetworzenie identyfikatorów URI, jeśli ich identyfikatory schematu są niezgodne. W takim przypadku zainicjuj dotknięte części aplikacji, gdy są potrzebne identyfikatory URI, a nie w czasie rozpoczęcia.