Classe System.Uri
Este artigo fornece observações complementares à documentação de referência para esta 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.
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 com escape, com todos os caracteres com valores Unicode maiores que 127 substituídos por seus equivalentes hexadecimais. Para colocar o URI na forma canônica, 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 números de porta padrão e vazios.
Converte caminhos de arquivo implícitos sem o esquema file:// (por exemplo, "C:\my\file") em caminhos de arquivo explícitos com o esquema file://.
Os caracteres com escape (também conhecidos como octetos codificados por percentagem) que não têm uma finalidade reservada são descodificados (também conhecidos como não escapados). Esses caracteres sem reserva 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 // (quer a sequência seja 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 encerrado com uma barra (/), uma será adicionada.
Por padrão, todos os caracteres reservados no URI são escapados de acordo com a RFC 2396. Esse comportamento muda se Identificadores de recursos internacionais ou análise de nome de domínio internacional estiver habilitada, caso em que caracteres reservados no URI são escapados de acordo com RFC 3986 e RFC 3987.
Como parte da canonicalização no construtor para alguns esquemas, segmentos de pontos e segmentos vazios (, , e ) são compactados (/./
em outras palavras, /../
//
eles são removidos). Os esquemas para os quais Uri os segmentos compactos 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 como a compactação parece na prática. As sequências escapadas não escapam, 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 para 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 dar 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.
Nota
A classe URI suporta o uso de endereços IP em notação quad para protocolo IPv4 e dois pontos-hexadecimais para 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 Web são normalmente expressos utilizando identificadores de recursos uniformes que consistem num conjunto muito restrito de carateres:
- Letras ASCII maiúsculas e minúsculas 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 para IRIs estão documentadas no 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, o IRI está sempre habilitado e não pode ser alterado usando uma opção de configuração. Você pode definir uma opção de configuração no arquivo machine.config ou no arquivo app.config para especificar se deseja que a análise IDN (Internationalized Domain Name) seja aplicada ao nome de domínio. Por exemplo:
<configuration>
<uri>
<idn enabled="All" />
</uri>
</configuration>
Habilitar o IDN converte todos os rótulos Unicode em um nome de domínio para seus equivalentes Punycode. Os nomes Punycode contêm apenas caracteres ASCII e sempre começam com o prefixo xn-. A razão para isso é suportar servidores DNS existentes na Internet, uma vez que a maioria dos servidores DNS suporta apenas caracteres ASCII (consulte RFC 3940).
A ativação do IDN afeta o Uri.DnsSafeHost valor da propriedade. Habilitar o IDN também pode alterar o Equalscomportamento dos métodos , , GetComponents, OriginalStringe IsWellFormedOriginalString .
Há três valores possíveis para IDN, dependendo dos servidores DNS usados:
idn ativado = Todos
Este valor irá converter quaisquer nomes de domínio Unicode para os seus equivalentes Punycode (nomes IDN).
idn ativado = AllExceptIntranet
Esse valor converterá todos os nomes de domínio Unicode que não estejam na Intranet local para usar os equivalentes Punycode (nomes IDN). Nesse caso, para lidar com nomes internacionais na Intranet local, os servidores DNS usados para a Intranet devem oferecer suporte à resolução de nomes Unicode.
idn ativado = Nenhum
Esse valor não converterá nenhum nome de domínio Unicode para usar Punycode. Este é o valor predefinido.
A normalização e a verificação de caracteres são feitas de acordo com as regras mais recentes do IRI no 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 setting. A System.Configuration.IriParsingElement configuração habilita ou desabilita o Uri processamento de IRI na classe. A System.Configuration.IdnElement configuração habilita ou desabilita o Uri processamento de IDN na classe.
A definição de configuração para o e System.Configuration.IdnElement é lida System.Configuration.IriParsingElement uma vez quando a primeira System.Uri classe é construída. As alterações nas definições de configuração após esse período são ignoradas.
A System.GenericUriParser classe também foi estendida para permitir a criação de um analisador personalizável que suporta IRI e IDN. O comportamento de um System.GenericUriParser objeto é especificado passando uma combinação bit a bit dos valores disponíveis na enumeração para o System.GenericUriParserOptionsSystem.GenericUriParser construtor. O GenericUriParserOptions.IriParsing tipo indica que o analisador suporta as regras de análise especificadas no RFC 3987 for International Resource Identifiers (IRI).
O GenericUriParserOptions.Idn tipo indica que o analisador suporta a análise de nomes de host de nome de domínio internacionalizado (IDN). No .NET 5 e versões posteriores (incluindo o .NET Core) e no .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 a caminhos de arquivos
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 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 estiver presente, Uri o padrão será 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 URI chamando o IsWellFormedOriginalString método.
Ao lidar com entradas de usuário não confiáveis, confirme as suposições sobre a instância recém-criada Uri
antes de confiar em suas propriedades.
Isto pode ser feito da seguinte forma:
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 de desempenho
Se você usar um arquivo Web.configque contenha URIs para inicializar seu aplicativo, será necessário mais tempo para processar os URIs se seus identificadores de esquema não forem padrão. Nesse caso, inicialize as partes afetadas do seu aplicativo quando os URIs forem necessários, não na hora do início.