System.Uri classe

Este artigo fornece observações complementares à documentação de referência para essa API.

Um URI é uma representação compacta de um recurso disponível para seu aplicativo na intranet ou na Internet. A Uri classe define as propriedades e os métodos para manipular URIs, incluindo análise, comparação e combinação. As Uri propriedades da classe são somente leitura; para criar um objeto modificável, use a UriBuilder classe.

Os URIs relativos (por exemplo, "/new/index.htm") devem ser expandidos em relação a um URI de base para que sejam absolutos. O MakeRelativeUri método é fornecido para converter URIs absolutos em URIs relativos quando necessário.

Os Uri construtores não escapam de cadeias de caracteres de URI se a cadeia de caracteres for um URI bem formado, incluindo um identificador de esquema.

As Uri propriedades retornam uma representação de dados canônica na codificação de escape, com todos os caracteres com valores Unicode maiores que 127 substituídos por seus equivalentes hexadecimais. Para colocar o URI no formato canônico, o Uri construtor executa as seguintes etapas:

  • Converte o esquema de URI em minúsculas.

  • Converte o nome do host em minúsculas.

  • Se o nome do host for um endereço IPv6, o endereço IPv6 canônico será usado. ScopeId e outros dados IPv6 opcionais são removidos.

  • Remove os números de porta padrão e vazios.

  • Converte caminhos de arquivo implícitos sem o esquema file:// (por exemplo, "C:\meu\arquivo") em caminhos de arquivo explícitos com o esquema file://.

  • Os caracteres de escape (também conhecidos como octetos codificados por porcentagem) que não têm uma finalidade reservada são decodificados (também conhecidos como não escapados). Esses caracteres não reservados incluem letras maiúsculas e minúsculas (%41-%5A e %61-%7A), dígitos decimais (%30-%39), hífen (%2D), ponto (%2E), sublinhado (%5F) e til (%7E).

  • Canonicaliza o caminho para URIs hierárquicos compactando sequências como /./, /.. /, e // (se a sequência está ou não escapada). Observe que existem alguns esquemas para os quais essas sequências não são compactadas.

  • Para URIs hierárquicos, se o host não for terminado com uma barra (/), um será adicionado.

  • Por padrão, todos os caracteres reservados no URI são escapados de acordo com a RFC 2396. Esse comportamento será alterado se a análise de identificadores de recursos internacionais ou de nome de domínio internacional estiver habilitada, caso em que os caracteres reservados no URI serão escapados de acordo com RFC 3986 e RFC 3987.

Como parte da canonização no construtor para alguns esquemas, segmentos de ponto e segmentos vazios (, e //) são compactados (/./em outras palavras, /../eles são removidos). Os esquemas para os quais Uri compacta segmentos incluem http, https, tcp, net.pipe e net.tcp. Para alguns outros esquemas, essas sequências não são compactadas. O trecho de código a seguir mostra a aparência da compactação na prática. As sequências escapadas são não escapadas, se necessário, e depois compactadas.

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 esse código é executado, ele retorna uma saída semelhante ao texto a seguir.

AbsoluteUri: http://myurl/
PathAndQuery: /

Você pode transformar o Uri conteúdo da classe de uma referência de URI codificada de escape em uma referência de URI legível usando o ToString método. Observe que alguns caracteres reservados ainda podem ser escapados na saída do ToString método. Isso é para oferecer suporte à reconstrução inequívoca de um URI a partir do valor retornado pelo ToString.

Alguns URIs incluem um identificador de fragmento ou uma consulta ou ambos. Um identificador de fragmento é qualquer texto que segue um sinal numérico (#), não incluindo o sinal numérico; O texto do fragmento Fragment é armazenado na propriedade. Informações de consulta são qualquer texto que segue um ponto de interrogação (?) no URI; O texto da Query consulta é armazenado na propriedade.

Observação

A classe URI oferece suporte ao uso de endereços IP em notação quádrupla para o protocolo IPv4 e dois pontos hexadecimais para o protocolo IPv6. Lembre-se de colocar o endereço IPv6 entre colchetes, como em http://[::1].

Suporte a identificadores de recursos internacionais

Os endereços da Web são normalmente expressos usando identificadores de recursos uniformes que consistem em um conjunto muito restrito de caracteres:

  • Letras maiúsculas e minúsculas ASCII do alfabeto inglês.
  • Dígitos de 0 a 9.
  • Um pequeno número de outros símbolos ASCII.

As especificações para URIs estão documentadas em RFC 2396, RFC 2732, RFC 3986 e RFC 3987 publicadas pela Internet Engineering Task Force (IETF).

Os identificadores que facilitam a necessidade de identificar recursos usando idiomas diferentes do inglês e permitem caracteres não-ASCII (caracteres no conjunto de caracteres Unicode/ISO 10646) são conhecidos como Identificadores de Recursos Internacionais (IRIs). As especificações de IRIs estão documentadas na RFC 3987, publicado pela IETF. O uso de IRIs permite que uma URL contenha caracteres Unicode.

No .NET Framework 4.5 e versões posteriores, a IRI está sempre habilitada e não pode ser alterada usando uma opção de configuração. Você pode definir uma opção de configuração no machine.config ou no arquivo app.config para especificar se deseja que a análise de IDN (Nome de Domínio Internacionalizado) seja aplicada ao nome de domínio. Por exemplo:

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

A habilitação do IDN converte todos os rótulos Unicode em um nome de domínio em seus equivalentes Punycode. Os nomes Punycode contêm apenas caracteres ASCII e sempre começam com o prefixo xn--. A razão para isso é dar suporte a servidores DNS existentes na Internet, pois a maioria dos servidores DNS dá suporte somente a caracteres ASCII (consulte RFC 3940).

A habilitação do IDN afeta o Uri.DnsSafeHost valor da propriedade. A habilitação do IDN também pode alterar o comportamento dos Equalsmétodos , , OriginalStringGetComponentse IsWellFormedOriginalString .

Há três valores possíveis para IDN, dependendo dos servidores DNS que são usados:

  • idn habilitado = Todos

    Esse valor converterá todos os nomes de domínio Unicode em seus equivalentes do Punycode (nomes IDN).

  • idn habilitado = AllExceptIntranet

    Esse valor converterá todos os nomes de domínio Unicode não na intranet local para usar os equivalentes do Punycode (nomes IDN). Nesse caso, para manipular nomes internacionais na Intranet local, os servidores DNS usados para a Intranet devem dar suporte a resolução de nomes Unicode.

  • idn habilitado = Nenhum

    Esse valor não converterá nenhum nome de domínio Unicode para usar o Punycode. Este é o valor padrão.

A normalização e a verificação de caracteres são feitas de acordo com as regras IRI mais recentes na RFC 3986 e RFC 3987.

O processamento de IRI e IDN na Uri classe também pode ser controlado usando as System.Configuration.IriParsingElementclasses , System.Configuration.IdnElemente System.Configuration.UriSection configuration definition. A configuração System.Configuration.IriParsingElement habilita ou desabilita o processamento de IRI na classe Uri. A configuração System.Configuration.IdnElement habilita ou desabilita o processamento de IDN na classe Uri.

A definição de configuração para o e System.Configuration.IdnElement são lidos System.Configuration.IriParsingElement uma vez quando a primeira System.Uri classe é construída. Alterações nas configurações depois desse tempo serão ignoradas.

A classe System.GenericUriParser também foi estendida para permitir a criação de um analisador personalizável que dá suporte a IRI e IDN. O comportamento de um objeto System.GenericUriParser é especificado passando-se uma combinação bit a bit dos valores disponíveis na enumeração System.GenericUriParserOptions para o construtor System.GenericUriParser. O tipo GenericUriParserOptions.IriParsing que indica que o analisador dá suporte às regras de análise especificadas na RFC 3987 para IRI (Identificadores de Recurso Internacional).

O GenericUriParserOptions.Idn tipo indica que o analisador oferece suporte à análise de nomes de host de nome de domínio internacionalizado (IDN). No .NET 5 e versões posteriores (incluindo .NET Core) e .NET Framework 4.5+, o IDN é sempre usado. Em versões anteriores, uma opção de configuração determina se o IDN é usado.

Suporte implícito ao caminho do arquivo

Uri também pode ser usado para representar caminhos do sistema de arquivos local. Esses caminhos podem ser representados explicitamente em URIs que começam com o esquema file:// e implicitamente em URIs que não têm o esquema file://. Como um exemplo concreto, os dois URIs a seguir são válidos e representam o mesmo caminho de arquivo:

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.

Esses caminhos de arquivo implícitos não são compatíveis com a especificação de URI e, portanto, devem ser evitados quando possível. Ao usar o .NET Core em sistemas baseados em Unix, os caminhos de arquivo implícitos podem ser especialmente problemáticos, porque um caminho de arquivo implícito absoluto é indistinguível de um caminho relativo. Quando essa ambiguidade está presente, Uri o padrão é interpretar o caminho como um URI absoluto.

Considerações de segurança

Devido a preocupações de segurança, seu aplicativo deve ter cuidado ao aceitar Uri instâncias de fontes não confiáveis e com dontEscape definido como true no construtor. Você pode verificar a validade de uma cadeia de caracteres de URI chamando o IsWellFormedOriginalString método.

Ao lidar com entrada de usuário não confiável, confirme suposições sobre a instância recém-criada Uri antes de confiar em suas propriedades. Isso pode ser feito da seguinte maneira:

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

Essa validação pode ser usada em outros casos, como ao lidar com caminhos UNC, simplesmente alterando o baseUri:

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

Considerações sobre o desempenho

Se você usar um arquivo Web.configque contém URIs para inicializar seu aplicativo, será necessário tempo adicional para processar os URIs se seus identificadores de esquema não forem padrão. Nesse caso, inicialize as partes afetadas do aplicativo quando os URIs forem necessários, não na hora de início.