System.Uri-klass

Anmärkning

Den här artikeln innehåller ytterligare kommentarer till referensdokumentationen för det här API:et.

En enhetlig resursidentifierare (URI) är en kompakt representation av en resurs som är tillgänglig för ditt program på intranätet eller Internet. Klassen Uri definierar egenskaper och metoder för hantering av URI:er, inklusive parsning, jämförelse och kombination. Klassegenskaperna Uri är skrivskyddade. Använd UriBuilder klassen för att skapa ett ändringsbart objekt.

Relativa URI:er (till exempel "/new/index.htm") måste utökas med avseende på en bas-URI så att de är absoluta. Metoden MakeRelativeUri tillhandahålls för att konvertera absoluta URI:er till relativa URI:er vid behov.

Konstruktorerna Uri eskaperar inte URI-strängar om strängen är en korrekt formaterad URI, inklusive ett schemanamn.

Egenskaperna Uri returnerar en kanonisk datarepresentation i undantagen kodning, där alla tecken med Unicode-värden som är större än 127 ersätts med deras hexadecimala motsvarigheter. Konstruktorn utför följande steg för att placera URI:n i kanonisk form Uri :

  • Konverterar URI-schemat till gemener.
  • Konverterar värdnamnet till småbokstäver.
  • Om värdnamnet är en IPv6-adress används den kanoniska IPv6-adressen. ScopeId och andra valfria IPv6-data tas bort.
  • Tar bort standard- och tomma portnummer.
  • Konverterar implicita filsökvägar utan file:// -schemat (till exempel "C:\my\file") till explicita filsökvägar med file://-schemat.
  • Undantagna tecken (även kallade procentkodade oktetter) som inte har ett reserverat syfte avkodas (kallas även ej kapslade). Dessa oreserverade tecken inkluderar versaler och gemener (%41-%5A och %61-%7A), decimalsiffror (%30-%39), bindestreck (%2D), period (%2E), understreck (%5F) och tilde (%7E).
  • Kanoniserar sökvägen för hierarkiska URI:er genom att komprimera sekvenser som /./ och /../ (oavsett om sekvensen är undantagen eller inte). Observera att det finns vissa scheman som dessa sekvenser inte komprimeras för.
  • För hierarkiska URI:er läggs ett till om värden inte avslutas med ett snedstreck (/).
  • Som standard är alla reserverade tecken i URI:n undantagna i enlighet med RFC 2396. Det här beteendet ändras om international resource identifiers eller international domain name parsing är aktiverad i vilket fall reserverade tecken i URI:n är undantagna i enlighet med RFC 3986 och RFC 3987.

Som en del av kanonisering i konstruktorn för vissa scheman komprimeras punktsegment (/./ och /../) (med andra ord tas de bort). De scheman som Uri komprimerar segment är http, https, tcp, net.pipe och net.tcp. För vissa andra scheman komprimeras inte dessa sekvenser. Följande kodfragment visar hur komprimering ser ut i praktiken. Escape-sekvenserna avkapslas, om det behövs, och komprimeras sedan.

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}");

När den här koden körs returneras utdata som liknar följande text.

AbsoluteUri: http://myurl/
PathAndQuery: /

Du kan transformera innehållet i Uri klassen från en escape-kodad URI-referens till en läsbar URI-referens med hjälp ToString av metoden. Observera att vissa reserverade tecken fortfarande kan vara undantagna i metodens ToString utdata. Detta är för att stödja en entydig rekonstruktion av en URI från värdet som returneras av ToString.

Vissa URI:er innehåller en fragmentidentifierare eller en fråga eller båda. En fragmentidentifierare är all text som följer ett taltecken (#), som inte inkluderar taltecknet. fragmenttexten lagras i egenskapen Fragment . Frågeinformation är en text som följer ett frågetecken (?) i URI:n. frågetexten lagras i egenskapen Query .

Anmärkning

URI-klassen stöder användning av IP-adresser i både quad-notation för IPv4-protokollet och colon-hexadecimalt för IPv6-protokollet. Kom ihåg att omsluta IPv6-adressen inom hakparenteser, som i http://[::1].

Stöd för internationella resursidentifierare

Webbadresser uttrycks vanligtvis med URI:er som består av en mycket begränsad uppsättning tecken:

  • Versaler och gemener ASCII-bokstäver från det engelska alfabetet.
  • Siffror från 0 till 9.
  • Ett litet antal andra ASCII-symboler.

Specifikationerna för URI:er dokumenteras i RFC 2396, RFC 2732, RFC 3986 och RFC 3987 publicerade av Internet Engineering Task Force (IETF).

Identifierare som underlättar behovet av att identifiera resurser med andra språk än engelska och tillåter icke-ASCII-tecken (tecken i Unicode/ISO 10646-teckenuppsättningen) kallas internationella resursidentifierare (IRI). Specifikationerna för IRI:er dokumenteras i RFC 3987 som publicerats av IETF. Med IRI:er kan en URL innehålla Unicode-tecken.

I .NET Framework 4.5 och senare versioner är IRI alltid aktiverat och kan inte ändras med ett konfigurationsalternativ. Du kan ange ett konfigurationsalternativ i machine.config eller i filenapp.config för att ange om du vill att parsning av internationaliserat domännamn (IDN) ska tillämpas på domännamnet. Till exempel:

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

Aktivering av IDN konverterar alla Unicode-etiketter i ett domännamn till deras Punycode-motsvarigheter. Punycode-namn innehåller bara ASCII-tecken och börjar alltid med prefixet xn. Anledningen till detta är att stödja befintliga DNS-servrar på Internet, eftersom de flesta DNS-servrar endast stöder ASCII-tecken (se RFC 3940).

Aktivering av IDN påverkar värdet för Uri.DnsSafeHost egenskapen. Aktivering av IDN kan också ändra beteendet för Equalsmetoderna , OriginalString, GetComponentsoch IsWellFormedOriginalString .

Det finns tre möjliga värden för IDN beroende på vilka DNS-servrar som används:

  • idn aktiverat = Alla

    Konverterar alla Unicode-domännamn till deras Punycode-motsvarigheter (IDN-namn).

  • idn aktiverat = AllExceptIntranet

    Konverterar alla Unicode-domännamn som inte finns i det lokala intranätet till att använda Punycode-motsvarigheterna (IDN-namn). I det här fallet, för att hantera internationella namn på det lokala intranätet, bör DNS-servrarna som används för intranätet ha stöd för Unicode-namnmatchning.

  • idn aktiverat = Ingen

    Inga Unicode-domännamn konverteras för att använda Punycode. Det här är standardvärdet.

Normaliserings- och teckenkontroll utförs enligt de senaste IRI-reglerna i RFC 3986 och RFC 3987.

IRI- och IDN-bearbetning i Uri klassen kan också styras med hjälp av klasserna System.Configuration.IriParsingElement, System.Configuration.IdnElementoch System.Configuration.UriSection konfigurationsinställning. Inställningen System.Configuration.IriParsingElement aktiverar eller inaktiverar IRI-bearbetning i Uri klassen. Inställningen System.Configuration.IdnElement aktiverar eller inaktiverar IDN-bearbetning i Uri klassen.

Konfigurationsinställningarna för System.Configuration.IriParsingElement och System.Configuration.IdnElement läses en gång när den första System.Uri-klassen skapas. Ändringar i konfigurationsinställningarna efter den tiden ignoreras.

Klassen System.GenericUriParser har också utökats så att du kan skapa en anpassningsbar parser som stöder IRI och IDN. Beteendet för ett System.GenericUriParser objekt anges genom att en bitvis kombination av de värden som är tillgängliga i System.GenericUriParserOptions uppräkningen skickas System.GenericUriParser till konstruktorn. Typen GenericUriParserOptions.IriParsing anger att parsern stöder de parsningsregler som anges i RFC 3987 för IRI (International Resource Identifiers).

Typen GenericUriParserOptions.Idn anger att parsern stöder internationaliserad domännamnsparsning (IDN) för värdnamn. I .NET 5 och senare versioner (inklusive .NET Core) och .NET Framework 4.5+, används alltid IDN. I tidigare versioner avgör ett konfigurationsalternativ om IDN används.

Stöd för implicit filsökväg

Uri kan också användas för att representera lokala filsystemsökvägar. Dessa sökvägar kan uttryckligen representeras i URI:er som börjar med file://-schemat och implicit i URI:er som inte har file://-schemat. Som ett konkret exempel är följande två URI:er båda giltiga och representerar samma filsökväg:

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.

Dessa implicita filsökvägar är inte kompatibla med URI-specifikationen och bör undvikas när det är möjligt. När du använder .NET Core i Unix-baserade system kan implicita filsökvägar vara särskilt problematiska, eftersom en absolut implicit filsökväg inte kan skiljas från en relativ sökväg. När en sådan tvetydighet finns, ska sökvägen tolkas som en absolut URI som standard.

Säkerhetsfrågor

På grund av säkerhetsskäl bör ditt program vara försiktigt när det accepteras Uri-instanser från opålitliga källor och att dontEscape är inställt på true i konstruktorn. Du kan kontrollera att en URI-sträng är giltig genom att anropa IsWellFormedOriginalString metoden.

När du hanterar ej betrodda användarindata bekräftar du antaganden om den nyligen skapade Uri instansen innan du litar på dess egenskaper. Detta kan göras på följande sätt:

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.
}

Den här valideringen kan användas i andra fall, till exempel när du hanterar UNC-sökvägar, genom att helt enkelt ändra :baseUri

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

Mer information om design- och säkerhetsöverväganden för Uri och UriBuilder finns i följande hotmodelldokument.

Prestandaöverväganden

Om du använder en Web.config fil som innehåller URI:er för att initiera programmet krävs ytterligare tid för att bearbeta URI:erna om deras schemaidentifierare inte är standard. I sådana fall initierar du de berörda delarna av programmet när URI:erna behövs, inte vid starttiden.