System.Uri-klasse
In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.
Een URI is een compacte weergave van een resource die beschikbaar is voor uw toepassing op het intranet of internet. De Uri klasse definieert de eigenschappen en methoden voor het verwerken van URI's, waaronder parseren, vergelijken en combineren. De Uri klasse-eigenschappen zijn alleen-lezen. Als u een wijzigbaar object wilt maken, gebruikt u de UriBuilder klasse.
Relatieve URI's (bijvoorbeeld '/new/index.htm') moeten worden uitgebreid met betrekking tot een basis-URI, zodat ze absoluut zijn. De MakeRelativeUri methode wordt gegeven om absolute URI's zo nodig te converteren naar relatieve URI's.
De Uri constructors ontsnappen niet aan URI-tekenreeksen als de tekenreeks een goed gevormde URI is, inclusief een schema-id.
De Uri eigenschappen retourneren een canonieke gegevensweergave in escape-codering, waarbij alle tekens met Unicode-waarden groter dan 127 zijn vervangen door hun hexadecimale equivalenten. Als u de URI in canonieke vorm wilt plaatsen, voert de Uri constructor de volgende stappen uit:
Converteert het URI-schema naar kleine letters.
Converteert de hostnaam naar kleine letters.
Als de hostnaam een IPv6-adres is, wordt het canonieke IPv6-adres gebruikt. ScopeId en andere optionele IPv6-gegevens worden verwijderd.
Hiermee verwijdert u standaard- en lege poortnummers.
Converteert impliciete bestandspaden zonder het file:// schema (bijvoorbeeld 'C:\my\file') naar expliciete bestandspaden met het file:// schema.
Escape-tekens (ook wel bekend als octetten met procentcodering) die geen gereserveerd doel hebben, worden gedecodeerd (ook wel unescaped genoemd). Deze niet-gereserveerde tekens bevatten hoofdletters en kleine letters (%41-%5A en %61-%7A), decimale cijfers (%30-%39), afbreekstreepje (%2D), punt (%2E), onderstrepingsteken (%5F) en tilde (%7E).
Canonicaliseert het pad voor hiërarchische URI's door reeksen zoals /./, /.. te comprimeren. /, en // (of de reeks al dan niet is ontsnapt). Houd er rekening mee dat er een aantal schema's zijn waarvoor deze reeksen niet worden gecomprimeerd.
Voor hiërarchische URI's wordt er een toegevoegd als de host niet wordt beëindigd met een slash (/).
Standaard worden gereserveerde tekens in de URI ontsnapt volgens RFC 2396. Dit gedrag verandert als International Resource Identifiers of International Domain Name Parsing is ingeschakeld in welk geval gereserveerde tekens in de URI worden ontsnapt in overeenstemming met RFC 3986 en RFC 3987.
Als onderdeel van canonicalisatie in de constructor voor sommige schema's, worden puntsegmenten en lege segmenten (, /../
en //
) gecomprimeerd (/./
met andere woorden, ze worden verwijderd). De schema's waarvoor Uri segmenten worden gecomprimeerd, zijn http, https, tcp, net.pipe en net.tcp. Voor sommige andere schema's worden deze reeksen niet gecomprimeerd. In het volgende codefragment ziet u hoe comprimeren er in de praktijk uitziet. De escape-reeksen zijn ongezichtloos, indien nodig, en vervolgens gecomprimeerd.
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}");
Wanneer deze code wordt uitgevoerd, wordt uitvoer geretourneerd die vergelijkbaar is met de volgende tekst.
AbsoluteUri: http://myurl/
PathAndQuery: /
U kunt de inhoud van de Uri klasse transformeren van een escape-gecodeerde URI-verwijzing naar een leesbare URI-verwijzing met behulp van de ToString methode. Houd er rekening mee dat sommige gereserveerde tekens mogelijk nog steeds worden ontsnapt in de uitvoer van de ToString methode. Dit is ter ondersteuning van ondubbelzinnige reconstructie van een URI van de waarde die wordt geretourneerd door ToString.
Sommige URI's bevatten een fragment-id of een query of beide. Een fragment-id is een tekst die volgt op een nummerteken (#), niet inclusief het nummerteken; de fragmenttekst wordt opgeslagen in de Fragment eigenschap. Querygegevens zijn tekst die volgt op een vraagteken (?) in de URI; de querytekst wordt opgeslagen in de Query eigenschap.
Notitie
De URI-klasse ondersteunt het gebruik van IP-adressen in zowel quad-notatie voor IPv4-protocol als dubbele hexadecimaal voor IPv6-protocol. Vergeet niet om het IPv6-adres tussen vierkante haken te sluiten, zoals in http://[::1].
Ondersteuning voor internationale resource-id's
Webadressen worden meestal uitgedrukt met behulp van uniforme resource-id's die bestaan uit een zeer beperkte set tekens:
- ASCII-letters in hoofdletters en kleine letters uit het Engelse alfabet.
- Cijfers van 0 tot 9.
- Een klein aantal andere ASCII-symbolen.
De specificaties voor URI's worden beschreven in RFC 2396, RFC 2732, RFC 3986 en RFC 3987 gepubliceerd door de Internet Engineering Task Force (IETF).
Id's die de noodzaak vergemakkelijken om resources te identificeren met andere talen dan Engels en niet-ASCII-tekens (tekens in de Unicode/ISO 10646-tekenset) worden ook wel International Resource Identifiers (IRI's) genoemd. De specificaties voor IURI's worden beschreven in RFC 3987 gepubliceerd door IETF. Als u IRI's gebruikt, kan een URL Unicode-tekens bevatten.
In .NET Framework 4.5 en latere versies is IRI altijd ingeschakeld en kan IRI niet worden gewijzigd met behulp van een configuratieoptie. U kunt een configuratieoptie instellen in de machine.config of in het bestand app.config om op te geven of u idN-parsering (Internationalized Domain Name) wilt toepassen op de domeinnaam. Voorbeeld:
<configuration>
<uri>
<idn enabled="All" />
</uri>
</configuration>
Als u IDN inschakelt, worden alle Unicode-labels in een domeinnaam geconverteerd naar hun Punycode-equivalenten. Punycodenamen bevatten alleen ASCII-tekens en beginnen altijd met het xn-voorvoegsel. De reden hiervoor is om bestaande DNS-servers op internet te ondersteunen, omdat de meeste DNS-servers alleen ASCII-tekens ondersteunen (zie RFC 3940).
Het inschakelen van IDN is van invloed op de waarde van de Uri.DnsSafeHost eigenschap. Het inschakelen van IDN kan ook het gedrag van de Equals, OriginalStringen GetComponentsIsWellFormedOriginalString methoden wijzigen.
Er zijn drie mogelijke waarden voor IDN, afhankelijk van de DNS-servers die worden gebruikt:
idn ingeschakeld = Alle
Met deze waarde worden unicode-domeinnamen geconverteerd naar hun Punycode-equivalenten (IDN-namen).
idn ingeschakeld = AllExceptIntranet
Met deze waarde worden alle Unicode-domeinnamen die niet op het lokale intranet staan, geconverteerd om de Punycode-equivalenten (IDN-namen) te gebruiken. In dit geval moeten de DNS-servers die voor het intranet worden gebruikt, internationale namen verwerken op het lokale intranet ondersteuning voor Unicode-naamomzetting.
idn ingeschakeld = Geen
Met deze waarde worden geen Unicode-domeinnamen geconverteerd om Punycode te gebruiken. Dit is de standaardwaarde.
Normalisatie en tekencontrole worden uitgevoerd volgens de nieuwste IRI-regels in RFC 3986 en RFC 3987.
IRI- en IDN-verwerking in de Uri klasse kunnen ook worden beheerd met behulp van de System.Configuration.IriParsingElementklassen en System.Configuration.IdnElementSystem.Configuration.UriSection configuratie-instellingen. De System.Configuration.IriParsingElement instelling schakelt IRI-verwerking in of uit in de Uri klasse. De System.Configuration.IdnElement instelling schakelt idN-verwerking in of uit in de Uri klasse.
De configuratie-instelling voor de System.Configuration.IriParsingElement en System.Configuration.IdnElement worden eenmaal gelezen wanneer de eerste System.Uri klasse wordt samengesteld. Wijzigingen in configuratie-instellingen na die tijd worden genegeerd.
De System.GenericUriParser klasse is ook uitgebreid om een aanpasbare parser te maken die ondersteuning biedt voor IRI en IDN. Het gedrag van een System.GenericUriParser object wordt opgegeven door een bitwise combinatie van de waarden die beschikbaar zijn in de System.GenericUriParserOptions opsomming door te geven aan de System.GenericUriParser constructor. Het GenericUriParserOptions.IriParsing type geeft aan dat de parser de parseerregels ondersteunt die zijn opgegeven in RFC 3987 voor International Resource Identifiers (IRI).
Het GenericUriParserOptions.Idn type geeft aan dat de parser ondersteuning biedt voor het parseren van hostnamen (Internationalized Domain Name). In .NET 5 en latere versies (inclusief .NET Core) en .NET Framework 4.5+ wordt IDN altijd gebruikt. In eerdere versies bepaalt een configuratieoptie of IDN wordt gebruikt.
Ondersteuning voor impliciet bestandspad
Uri kan ook worden gebruikt om lokale bestandssysteempaden weer te geven. Deze paden kunnen expliciet worden weergegeven in URI's die beginnen met het file:// schema en impliciet in URI's die niet over het file:// schema beschikken. Als concreet voorbeeld zijn de volgende twee URI's beide geldig en vertegenwoordigen hetzelfde bestandspad:
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.
Deze impliciete bestandspaden voldoen niet aan de URI-specificatie en moeten dus indien mogelijk worden vermeden. Wanneer u .NET Core op Unix-systemen gebruikt, kunnen impliciete bestandspaden met name problematisch zijn, omdat een absoluut impliciet bestandspad niet kan worden onderscheiden van een relatief pad. Wanneer dergelijke dubbelzinnigheid aanwezig is, Uri wordt het pad standaard geïnterpreteerd als een absolute URI.
Beveiligingsoverwegingen
Vanwege beveiligingsproblemen moet uw toepassing voorzichtig zijn bij het accepteren Uri van exemplaren van niet-vertrouwde bronnen en ingesteld dontEscape
true
op in de constructor. U kunt een URI-tekenreeks controleren op geldigheid door de methode aan te IsWellFormedOriginalString roepen.
Als u te maken hebt met niet-vertrouwde gebruikersinvoer, bevestigt u veronderstellingen over het zojuist gemaakte Uri
exemplaar voordat u de eigenschappen ervan vertrouwt.
Dit kan op de volgende manier:
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.
}
Deze validatie kan worden gebruikt in andere gevallen, zoals bij het omgaan met UNC-paden, door simpelweg het baseUri
volgende te wijzigen:
Uri baseUri = new Uri(@"\\host\share\some\directory\name\");
Prestatieoverwegingen
Als u een Web.config-bestandgebruikt dat URI's bevat om uw toepassing te initialiseren, is er extra tijd nodig om de URI's te verwerken als hun schema-id's niet standaard zijn. Initialiseer in dat geval de betrokken onderdelen van uw toepassing wanneer de URI's nodig zijn, niet op het begintijd.