Compartir a través de


Clase System.Uri

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

Un identificador uniforme de recursos (URI) es una representación compacta de un recurso disponible para la aplicación en la intranet o En Internet. La Uri clase define las propiedades y los métodos para controlar los URI, incluido el análisis, la comparación y la combinación. Las Uri propiedades de clase son de solo lectura; para crear un objeto modificable, use la UriBuilder clase .

Los URI relativos (por ejemplo, "/new/index.htm") deben expandirse con respecto a un URI base para que sean absolutos. El MakeRelativeUri método se proporciona para convertir los URI absolutos en URI relativos cuando sea necesario.

Los constructores Uri no escapan a las cadenas de URI si la cadena es un URI bien formado, incluido un identificador de esquema.

Las Uri propiedades devuelven una representación de datos canónica en codificación con escape, con todos los caracteres con valores Unicode mayores que 127 reemplazados por sus equivalentes hexadecimales. Para colocar el URI en forma canónica, el Uri constructor realiza los pasos siguientes:

  • Convierte el esquema URI en minúsculas.
  • Convierte el nombre de host en minúsculas.
  • Si el nombre de host es una dirección IPv6, se usa la dirección IPv6 canónica. ScopeId y otros datos IPv6 opcionales se quitan.
  • Quita los números de puerto predeterminados y vacíos.
  • Convierte rutas de acceso implícitas de archivo sin el esquema de file:// (por ejemplo, "C:\my\file") en rutas de acceso de archivo explícitas con el esquema file://.
  • Los caracteres de escape (también conocidos como octetos codificados por porcentaje) que no tienen un propósito reservado se descodifican (también conocidos como sin escape). Estos caracteres no reservados incluyen letras mayúsculas y minúsculas (%41-%5A y %61-%7A), dígitos decimales (%30-%39), guion (%2D), punto (%2E), guion bajo (%5F) y tilde (%7E).
  • Crea la versión canónica de la ruta para las URI jerárquicas mediante la compactación de secuencias como /./ y /../ (independientemente de si la secuencia está escapada). Tenga en cuenta que hay algunos esquemas para los que estas secuencias no están compactadas.
  • En el caso de los URI jerárquicos, si el host no finaliza con una barra diagonal (/), se agrega una.
  • De forma predeterminada, los caracteres reservados del URI se escapan de acuerdo con RFC 2396. Este comportamiento cambia si los identificadores de recursos internacionales o el análisis de nombres de dominio internacional están habilitados en cuyo caso los caracteres reservados en el URI se escapan de acuerdo con RFC 3986 y RFC 3987.

Como parte de la canonicalización en el constructor de algunos esquemas, los segmentos de puntos (/./ y /../) se compactan, por lo tanto, se eliminan. Los esquemas en los que Uri compacta segmentos incluyen http, https, tcp, net.pipe y net.tcp. Para algunos otros esquemas, estas secuencias no se compactan. En el siguiente fragmento de código se muestra cómo se ve la compactación en la práctica. Las secuencias de escape están sin escape, si es necesario, y luego se compactan.

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

Cuando se ejecuta este código, devuelve una salida similar al texto siguiente.

AbsoluteUri: http://myurl/
PathAndQuery: /

Puede transformar el contenido de la Uri clase de una referencia de URI codificada con escape a una referencia de URI legible mediante el ToString método . Tenga en cuenta que es posible que algunos caracteres reservados todavía se escapen en la salida del ToString método . Esto es para admitir la reconstrucción inequívoca de un URI a partir del valor devuelto por ToString.

Algunos URI incluyen un identificador de fragmento o una consulta o ambas. Un identificador de fragmento es cualquier texto que siga un signo de número (#), no incluido el signo de número; el texto del fragmento se almacena en la Fragment propiedad . La información de consulta es cualquier texto que siga un signo de interrogación (?) en el URI; el texto de la consulta se almacena en la Query propiedad .

Nota:

La clase URI admite el uso de direcciones IP en la notación cuádruple para IPv4 y en la notación hexadecimal con dos puntos para IPv6. No olvide incluir la dirección IPv6 entre corchetes, como en http://[::1].

Compatibilidad con identificadores de recursos internacionales

Las direcciones web normalmente se expresan mediante URI que constan de un conjunto de caracteres muy restringido:

  • Letras ASCII mayúsculas y minúsculas del alfabeto inglés.
  • Dígitos de 0 a 9.
  • Un pequeño número de otros símbolos ASCII.

Las especificaciones de los URI se documentan en RFC 2396, RFC 2732, RFC 3986 y RFC 3987 publicados por internet Engineering Task Force (IETF).

Los identificadores que facilitan la necesidad de identificar recursos que usan idiomas distintos del inglés y permiten caracteres no ASCII (caracteres en el juego de caracteres Unicode/ISO 10646) se conocen como identificadores de recursos internacionales (IRIs). Las especificaciones de las IRIs se documentan en RFC 3987 publicado por IETF. El uso de IRIs permite que una dirección URL contenga caracteres Unicode.

En .NET Framework 4.5 y versiones posteriores, IRI siempre está habilitado y no se puede cambiar con una opción de configuración. Puede establecer una opción de configuración en el machine.config o en el archivo app.config para especificar si desea analizar el nombre de dominio internacionalizado (IDN) aplicado al nombre de dominio. Por ejemplo:

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

Al habilitar IDN, se convierten todas las etiquetas Unicode de un nombre de dominio en sus equivalentes de Punycode. Los nombres punycode solo contienen caracteres ASCII y siempre comienzan con el prefijo xn-- . La razón de esto es admitir servidores DNS existentes en Internet, ya que la mayoría de los servidores DNS solo admiten caracteres ASCII (consulte RFC 3940).

La activación de IDN afecta al valor de la propiedad Uri.DnsSafeHost. La habilitación de IDN también puede cambiar el comportamiento de los métodos Equals, OriginalString, GetComponents y IsWellFormedOriginalString.

Hay tres valores posibles para IDN en función de los servidores DNS que se usan:

  • idn enabled = All

    Convierte los nombres de dominio Unicode en sus equivalentes de Punycode (nombres de IDN).

  • idn enabled = AllExceptIntranet

    Convierte todos los nombres de dominio Unicode que no están en la intranet local para usar los equivalentes de Punycode (nombres IDN). En este caso, para controlar nombres internacionales en la intranet local, los servidores DNS que se usan para la intranet deben admitir la resolución de nombres Unicode.

  • idn enabled = None

    No se convierte ningún nombre de dominio Unicode para usar Punycode. Este es el valor predeterminado.

La normalización y la comprobación de caracteres se realizan según las últimas reglas de IRI en RFC 3986 y RFC 3987.

El procesamiento de IRI e IDN en la clase Uri también se puede controlar mediante las clases de configuración System.Configuration.IriParsingElement, System.Configuration.IdnElement y System.Configuration.UriSection. La System.Configuration.IriParsingElement configuración habilita o deshabilita el procesamiento de IRI en la Uri clase . La System.Configuration.IdnElement configuración habilita o deshabilita el procesamiento de IDN en la Uri clase .

El valor de configuración de System.Configuration.IriParsingElement y System.Configuration.IdnElement se leen una vez cuando se construye la primera System.Uri clase. Los cambios en las opciones de configuración después de ese tiempo se omiten.

La System.GenericUriParser clase también se ha ampliado para permitir la creación de un analizador personalizable que admita IRI e IDN. El comportamiento de un System.GenericUriParser objeto se especifica pasando una combinación bit a bit de los valores disponibles en la System.GenericUriParserOptions enumeración al System.GenericUriParser constructor. El GenericUriParserOptions.IriParsing tipo indica que el analizador admite las reglas de análisis especificadas en RFC 3987 para identificadores de recursos internacionales (IRI).

El tipo GenericUriParserOptions.Idn indica que el analizador admite el análisis del Nombre de dominio internacionalizado (IDN) de los nombres de host. En .NET 5 y versiones posteriores (incluido .NET Core) y .NET Framework 4.5+, siempre se usa IDN. En versiones anteriores, una opción de configuración determina si se usa IDN.

Compatibilidad con ruta de archivo implícita

Uri también se puede usar para representar rutas de acceso del sistema de archivos locales. Estas rutas de acceso se pueden representar explícitamente en los URI que comienzan con el esquema de file:// y implícitamente en los URI que no tienen el esquema file://. Como ejemplo concreto, los dos URI siguientes son válidos y representan la misma ruta de acceso de archivo:

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.

Estas rutas de acceso implícitas de archivo no son compatibles con la especificación de URI y deben evitarse siempre que sea posible. Cuando se usa .NET Core en sistemas basados en Unix, las rutas de acceso implícitas a archivos pueden ser especialmente problemáticas, ya que una ruta de acceso de archivo implícita absoluta es indistinguible desde una ruta de acceso relativa. Cuando haya tal ambigüedad, Uri se debe interpretar por defecto la ruta de acceso como un URI absoluto.

Consideraciones de seguridad

Debido a problemas de seguridad, su aplicación debe tener precaución al aceptar Uri instancias de orígenes que no son de confianza y con dontEscape establecido a true en el constructor. Puede comprobar una cadena de URI para comprobar la validez llamando al IsWellFormedOriginalString método .

Al tratar con la entrada de usuario que no es de confianza, compruebe las suposiciones sobre la instancia recién creada Uri antes de confiar en sus propiedades. Esto se puede hacer de la siguiente manera:

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

Esta validación se puede usar en otros casos, como cuando se trabaja con rutas UNC, simplemente cambiando :baseUri

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

Consideraciones sobre el rendimiento

Si usa un archivo Web.config que contiene URI para inicializar la aplicación, se requiere tiempo adicional para procesar los URI si sus identificadores de esquema no son estándar. En tal caso, inicialice las partes afectadas de la aplicación cuando se necesiten los URI, no a la hora de inicio.