Cómo comprobar que una cadena uri es válida

82

¿Cómo se comprueba que una cadena de uri es válida (que se puede alimentar al constructor de Uri)?

Hasta ahora solo tengo lo siguiente, pero por razones obvias prefiero una forma menos bruta:

    Boolean IsValidUri(String uri)
    {
        try
        {
            new Uri(uri);
            return true;
        }
        catch
        {
            return false;
        }
    }

Probé Uri.IsWellFormedUriString pero no parece gustarle todo lo que puede lanzar al constructor. Por ejemplo:

String test = @"C:\File.txt";
Console.WriteLine("Uri.IsWellFormedUriString says: {0}", Uri.IsWellFormedUriString(test, UriKind.RelativeOrAbsolute));
Console.WriteLine("IsValidUri says: {0}", IsValidUri(test));

La salida será:

Uri.IsWellFormedUriString says: False
IsValidUri says: True

Actualizar / Responder

El constructor Uri usa kind Absolute por defecto. Esto estaba causando una discrepancia cuando intenté usar Uri.TryCreate y el constructor. Obtiene el resultado esperado si hace coincidir el UriKind tanto para el constructor como para TryCreate.

Manuel
fuente

Respuestas:

82

Un URI bien formado implica conformidad con ciertas RFC. La ruta local en su ejemplo no se ajusta a estos. Leer más en la IsWellFormedUriStringdocumentación.

Un resultado falso de ese método no implica que la Uriclase no pueda analizar la entrada. Si bien la entrada de URI puede no cumplir con RFC, aún puede ser un URI válido.

Actualización : Y para responder a su pregunta, como muestra la documentación de Uri, hay un método estático llamado TryCreateque intentará exactamente lo que desea y devolverá verdadero o falso (y la Uriinstancia real si es verdadera).

Franci Penov
fuente
La pregunta es "¿Cómo se comprueba que una cadena de uri es válida (que se puede alimentar al constructor de Uri)?"
Manuel
1
TryCreate realmente no le dice si el constructor aceptará una cadena. Ver actualización.
Manuel
@Manuel: eso no tiene ningún sentido - el resultado de TryCreatey el Uriconstructor deberían ser idénticos - intenta pasar lo UriKindque hiciste TryCreate.
BrokenGlass
1
Tienes razón. El constructor usa el tipo predeterminado Absolute. Gracias.
Manuel
3
Según las fuentes de .Net, el método IsWellFormedUriString contiene la llamada al método TryCreate más comprobaciones adicionales , por lo que prefiero usar el método IsWellFormedUriString como más poderoso para tales tareas.
Igor Kustov
43

Dado que la respuesta aceptada no proporciona un ejemplo explícito, aquí hay un código para validar los URI en C #:

Uri outUri;

if (Uri.TryCreate("ThisIsAnInvalidAbsoluteURI", UriKind.Absolute, out outUri)
   && (outUri.Scheme == Uri.UriSchemeHttp || outUri.Scheme == Uri.UriSchemeHttps))
{
    //Do something with your validated Absolute URI...
}
DiscDev
fuente
2
¡No confíe en la función Uri.TryCreate! Esto también permitirá URL incorrectas. Pruebe esto 'http: // http: // google.com/page' (elimine los espacios). Esta URL pasa la función TryCreate, pero es incorrecta.
No1Lives4Ever
5
@ No1Lives4Ever Tiene razón en que analiza como válido lo que mencionó, pero esto no es técnicamente incorrecto. La explicación en inglés: usando el protocolo http ( http: // ), conéctese a la entrada DNS para "http" (http: // ** http **) usando un puerto explícito (pero omitido) ( http **: * *) - entonces asumiré el predeterminado para el protocolo; proporcionó una carpeta de primer nivel vacía ( http : ** // **) pero sé lo que quiso decir;) seguida de un segmento de ruta "google.com" ( http: / ** google.com / **) y luego el recurso "página" ( http://google.com ** página **)
mlhDev
9

Suponiendo que solo queremos admitir solicitudes URI y HTTP absolutas, aquí hay una función que hace lo que desea:

public static bool IsValidURI(string uri)
{
    if (!Uri.IsWellFormedUriString(uri, UriKind.Absolute))
        return false;
    Uri tmp;
    if (!Uri.TryCreate(uri, UriKind.Absolute, out tmp))
        return false;
    return tmp.Scheme == Uri.UriSchemeHttp || tmp.Scheme == Uri.UriSchemeHttps;
}
cdiggins
fuente
1
La segunda verificación es necesaria para hacer posible la tercera (y última) verificación. Sin ella, no hay tmp. El primer paso es posiblemente redundante en este caso ...
Joe
1

En mi caso, solo quería probar el uri, no quiero ralentizar la aplicación que prueba el uri.

Boolean IsValidUri(String uri){
  return Uri.IsWellFormedUriString(uri, UriKind.Absolute);
}
Glauber Rodrigues
fuente
0

En su caso, el argumento uri es una ruta absoluta que se refiere a la ubicación de un archivo, por lo que, según el documento del método, devuelve falso. Consulte este

Vijay Sirigiri
fuente
Estoy usando UriKind.RelativeOrAbsolute, por lo que no debería importar. De cualquier manera, no funciona con UriKind.Relative o UriKind.Absolute, así que no hay suerte allí.
Manuel