Condividi tramite


Classe System.Uri

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

Un URI è una rappresentazione compatta di una risorsa disponibile per l'applicazione su Intranet o Internet. La Uri classe definisce le proprietà e i metodi per la gestione degli URI, tra cui l'analisi, il confronto e la combinazione. Le proprietà della Uri classe sono di sola lettura. Per creare un oggetto modificabile, usare la UriBuilder classe .

Gli URI relativi (ad esempio, "/new/index.htm") devono essere espansi rispetto a un URI di base in modo che siano assoluti. Il MakeRelativeUri metodo viene fornito per convertire gli URI assoluti in URI relativi, se necessario.

I Uri costruttori non eseguono l'escape delle stringhe URI se la stringa è un URI ben formato, incluso un identificatore di schema.

Le Uri proprietà restituiscono una rappresentazione di dati canonica nella codifica con escape, con tutti i caratteri con valori Unicode maggiori di 127 sostituiti con gli equivalenti esadecimali. Per inserire l'URI in formato canonico, il Uri costruttore esegue i passaggi seguenti:

  • Converte lo schema URI in lettere minuscole.

  • Converte il nome host in lettere minuscole.

  • Se il nome host è un indirizzo IPv6, viene usato l'indirizzo IPv6 canonico. ScopeId e altri dati IPv6 facoltativi vengono rimossi.

  • Rimuove i numeri di porta predefiniti e vuoti.

  • Converte i percorsi di file impliciti senza lo schema di file:// ,ad esempio "C:\my\file") in percorsi di file espliciti con lo schema file://.

  • I caratteri di escape (noti anche come ottetti con codifica percentuale) che non hanno uno scopo riservato vengono decodificati (noti anche come senza caratteri di escape). Questi caratteri non validi includono lettere maiuscole e minuscole (%41-%5A e %61-%7A), cifre decimali (%30-%39), trattino (%2D), punto (%2E), carattere di sottolineatura (%5F) e tilde (%7E).

  • Canonizza il percorso per gli URI gerarchici compattando sequenze come /./, /.. /, e // (indipendentemente dal fatto che la sequenza sia preceduta o meno da un escape). Si noti che esistono alcuni schemi per i quali queste sequenze non vengono compattate.

  • Per gli URI gerarchici, se l'host non viene terminato con una barra (/), ne viene aggiunto uno.

  • Per impostazione predefinita, tutti i caratteri riservati nell'URI vengono preceduti da escape in base a RFC 2396. Questo comportamento cambia se l'analisi international resource identifier o International Domain Nameing è abilitata nel qual caso i caratteri riservati nell'URI vengono preceduti da escape in base a RFC 3986 e RFC 3987.

Nell'ambito della canonizzazione nel costruttore per alcuni schemi, i segmenti dot e i segmenti vuoti (, /../e //) vengono compattati (/./in altre parole, vengono rimossi). Gli schemi per i quali Uri compatta i segmenti includono http, https, tcp, net.pipe e net.tcp. Per altri schemi, queste sequenze non vengono compattate. Il frammento di codice seguente mostra l'aspetto della compattazione pratica. Le sequenze di escape vengono senza caratteri di escape, se necessario, e quindi compattate.

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

Quando questo codice viene eseguito, restituisce un output simile al testo seguente.

AbsoluteUri: http://myurl/
PathAndQuery: /

È possibile trasformare il contenuto della Uri classe da un riferimento URI codificato con escape a un riferimento URI leggibile usando il ToString metodo . Si noti che alcuni caratteri riservati potrebbero comunque essere preceduti da un carattere di escape nell'output del ToString metodo . Ciò consente di supportare la ricostruzione non ambigua di un URI dal valore restituito da ToString.

Alcuni URI includono un identificatore di frammento o una query o entrambi. Un identificatore di frammento è qualsiasi testo che segue un segno di numero (#), senza includere il segno di numero; il testo del frammento viene archiviato nella Fragment proprietà . Le informazioni sulle query sono testo che segue un punto interrogativo (?) nell'URI; il testo della query viene archiviato nella Query proprietà .

Nota

La classe URI supporta l'uso di indirizzi IP sia nella notazione quad per il protocollo IPv4 che per il protocollo IPv4 e per il protocollo IPv6. Ricordarsi di racchiudere l'indirizzo IPv6 tra parentesi quadre, come in http://[::1].

Supporto dell'identificatore di risorsa internazionale

Gli indirizzi Web vengono in genere espressi usando identificatori di risorsa uniformi costituiti da un set di caratteri molto limitato:

  • Lettere ASCII maiuscole e minuscole dell'alfabeto inglese.
  • Cifre comprese tra 0 e 9.
  • Numero ridotto di altri simboli ASCII.

Le specifiche per gli URI sono documentate in RFC 2396, RFC 2732, RFC 3986 e RFC 3987 pubblicato da Internet Engineering Task Force (IETF).

Gli identificatori che facilitano la necessità di identificare le risorse usando lingue diverse dall'inglese e consentono caratteri non ASCII (caratteri nel set di caratteri Unicode/ISO 10646) sono noti come Identificatori di risorsa internazionali (IRIs). Le specifiche per gli IRI sono documentate nella nota RFC 3987, pubblicata da IETF. L'uso di IRI permette a un URL di includere caratteri Unicode.

In .NET Framework 4.5 e versioni successive, IRI è sempre abilitato e non può essere modificato usando un'opzione di configurazione. È possibile impostare un'opzione di configurazione nel file machine.config o nel file app.config per specificare se si vuole applicare l'analisi IDN (Internationalized Domain Name) al nome di dominio. Ad esempio:

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

L'abilitazione di IDN converte tutte le etichette Unicode in un nome di dominio negli equivalenti punycode. I nomi Punycode contengono solo caratteri ASCII e iniziano sempre con il prefisso "xn--". Questo avviene per supportare i server DNS esistenti in Internet, in quanto la maggior parte dei server DNS supporta solo caratteri ASCII. Vedere il documento RFC 3940.

L'abilitazione dell'IDN influisce sul valore della Uri.DnsSafeHost proprietà. L'abilitazione di IDN può anche modificare il comportamento dei Equalsmetodi , OriginalStringGetComponents, e IsWellFormedOriginalString .

Esistono tre valori possibili per IDN a seconda dei server DNS usati:

  • idn enabled = All

    Questo valore convertirà tutti i nomi di dominio Unicode nei rispettivi equivalenti Punycode (nomi IDN).

  • idn enabled = AllExceptIntranet

    Questo valore convertirà tutti i nomi di dominio Unicode non nella Intranet locale per usare gli equivalenti Punycode (nomi IDN). In questo caso per gestire i nomi internazionali nella Intranet locale, i server DNS usati per intranet devono supportare la risoluzione dei nomi Unicode.

  • idn enabled = Nessuno

    Questo valore non convertirà nomi di dominio Unicode per l'uso di Punycode. Questo è il valore predefinito.

La normalizzazione e il controllo dei caratteri vengono eseguiti in base alle regole IRI più recenti in RFC 3986 e RFC 3987.

L'elaborazione IRI e IDN nella Uri classe può anche essere controllata usando le System.Configuration.IriParsingElementclassi di impostazione di configurazione , System.Configuration.IdnElemente System.Configuration.UriSection . L'impostazione System.Configuration.IriParsingElement abilita o disabilita l'elaborazione degli IRI nella classe Uri. L'impostazione System.Configuration.IdnElement abilita o disabilita l'elaborazione degli IDN nella classe Uri.

L'impostazione di configurazione per System.Configuration.IriParsingElement e System.Configuration.IdnElement viene letta una volta quando viene costruita la prima System.Uri classe. Le modifiche apportate alle impostazioni di configurazione da questo momento in poi verranno ignorate.

La classe System.GenericUriParser è stata estesa anche per consentire la creazione di un parser personalizzabile che supporta gli IRI e gli IDN. Il comportamento di un oggetto System.GenericUriParser è specificato passando una combinazione bit per bit dei valori disponibili nell'enumerazione System.GenericUriParserOptions al costruttore System.GenericUriParser. Il tipo GenericUriParserOptions.IriParsing indica che il parser supporta le regole specificate nel documento RFC 3987 per gli IRI (International Resource Identifier).

Il GenericUriParserOptions.Idn tipo indica che il parser supporta l'analisi IDN (Internationalized Domain Name) dei nomi host. In .NET 5 e versioni successive (inclusi .NET Core) e .NET Framework 4.5+, viene sempre usato IDN. Nelle versioni precedenti, un'opzione di configurazione determina se viene usato L'IDN.

Supporto del percorso di file implicito

Uri può essere usato anche per rappresentare i percorsi del file system locale. Questi percorsi possono essere rappresentati in modo esplicito negli URI che iniziano con lo schema di file:// e in modo implicito negli URI che non hanno lo schema di file://. Come esempio concreto, i due URI seguenti sono entrambi validi e rappresentano lo stesso percorso di file:

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.

Questi percorsi di file impliciti non sono conformi alla specifica URI e pertanto devono essere evitati quando possibile. Quando si usa .NET Core nei sistemi basati su Unix, i percorsi di file impliciti possono risultare particolarmente problematici, perché un percorso di file implicito assoluto è indistinguibile da un percorso relativo. Quando tale ambiguità è presente, Uri per impostazione predefinita viene interpretato il percorso come URI assoluto.

Considerazioni sulla sicurezza

A causa di problemi di sicurezza, l'applicazione deve prestare attenzione quando si accettano Uri istanze da origini non attendibili e con dontEscape impostato su true nel costruttore. È possibile controllare la validità di una stringa URI chiamando il IsWellFormedOriginalString metodo .

Quando si usa l'input dell'utente non attendibile, verificare i presupposti relativi all'istanza appena creata Uri prima di considerare attendibili le relative proprietà. Questa operazione può essere eseguita nel modo seguente:

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

Questa convalida può essere usata in altri casi, ad esempio quando si gestiscono percorsi UNC, semplicemente modificando :baseUri

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

Considerazioni sulle prestazioni

Se si usa un file Web.configche contiene URI per inizializzare l'applicazione, è necessario ulteriore tempo per elaborare gli URI se gli identificatori dello schema non sono standard. In tal caso, inizializzare le parti interessate dell'applicazione quando sono necessari gli URI, non all'ora di inizio.