2010-09-09 2 views
9

Ho bisogno di un metodo di convalida Uri. Così, le stringhe come:Convalida Uri da stringa

"http://www.google.com", "www.google.com", "google.com"

..must essere convalidati come Uri di. E anche le normali stringhe come "google" non devono essere convalidate come quelle di Uri. Per fare questo controllo, utilizzo due metodi: UriBuilder e Uri.TryCreate().

Il problema con UriBuilder è che qualsiasi stringa che gli do, restituisce un Uri da esso. Quando passo una stringa normale nel suo costruttore, gli dà uno schema e restituisce "http://google/" che non è il comportamento che voglio.

Il problema con Uri.TryCreate() è che, mentre funziona bene con "http://www.google.com" e "www.google.com", quando gli do "google.com" non è valido come Uri.

Ho pensato di eseguire i controlli sulla stringa, se inizia con http: // o www, invia la stringa alla classe UriBuilder, ma questo non aiuta con "google.com" che deve essere anche un Uri.

Come posso convalidare cose come "google.com" come Uri, ma non "google"? Controllare la fine della stringa per .com, .net, .org non sembra flessibile.

+2

puoi verificare se stai cercando di convalidare un URL o un URI? La tua domanda è un po 'confusa. – slugster

+0

@Slugster - dopo aver letto la domanda ho controllato online per capire la differenza, quindi la risposta è che ho bisogno di convalidare un URI, non un URL. –

risposta

5
public static bool IsValidUri(string uriString) 
{ 
    Uri uri; 
    if (!uriString.Contains("://")) uriString = "http://" + uriString; 
    if (Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out uri)) 
    { 
     if (Dns.GetHostAddresses(uri.DnsSafeHost).Length > 0) 
     { 
      return true; 
     } 
    } 
    return false; 
} 
+1

Il protocollo può essere [diverse altre cose] (http://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Examples_of_absolute_URIs) diverso da HTTP. – slugster

+0

@slugster: Questo è il motivo per cui controlla se ha già un protocollo ... lo imposta solo su http se non lo fa .. che è di gran lunga il più comune ed è abbastanza sicuro da usare per default. – mpen

+0

Grazie per il tuo codice. Tuttavia questo codice costruisce un Uri da una singola parola - se passo "google" ottengo in cambio "http: // google /" che non è quello che mi serve. Inoltre vorrei evitare di costruire la logica del codice sui costrutti try/catch. –

15

Quello che stai cercando è Uri.IsWellFormedUriString. Il codice seguente restituisce true:

Uri.IsWellFormedUriString("google.com", UriKind.RelativeOrAbsolute) 

Se si imposta UriKind a Absolute, restituisce false:

Uri.IsWellFormedUriString("google.com", UriKind.Absolute) 

EDIT: Vedere here per UriKind enumerazione.

  • RelativeOrAbsolute: il tipo di Uri è indeterminato.
  • Assoluto: l'Uri è un assoluto Uri.
  • Parente: l'Uri è un Uri relativo.

Da MSDN documentation:

assoluto URI sono caratterizzati da un riferimento completo alla risorsa (esempio: http://www.contoso.com/index.html), mentre un parente Uri dipende da una base precedentemente definito URI (esempio: /index.html).

Inoltre, vedere here per Uri.IsWellFormedUriString. Questo metodo funziona in conformità con RFC 2396 e RFC 2732.

Se guardi allo RFC 2396, vedrai che google.com non è un URI valido. In realtà www.google.com non è né l'uno né l'altro. Ma sotto F. abbreviato URL, questo situtation è spiegato in dettaglio come segue:

La sintassi URL è stato progettato per riferimento inequivocabile alla rete risorse ed estensibilità tramite lo schema URL.Tuttavia, poiché l'identificazione e l'utilizzo dell'URL sono diventati comuni, i media tradizionali (televisione, radio, giornali, cartelloni pubblicitari, ecc.) Hanno sempre più spesso riferimenti URL abbreviati a . Ovvero, un riferimento costituito da solo l'autorizzazione e le porzioni di percorso della risorsa identificata, ad esempio www.w3.org/Addressing/ o semplicemente il nome host DNS da solo. Tali riferimenti sono principalmente destinati all'interpretazione umana piuttosto che alla macchina, con l'ipotesi che l'euristica basata sul contesto sia sufficiente per completare l' URL (ad esempio, la maggior parte dei nomi host che iniziano con "www" hanno probabilmente un prefisso URL di "http : // "). Sebbene non vi sia un set standard di euristica per il disambiguazione dei riferimenti URL abbreviati, molte implementazioni del client consentono di inserirle dall'utente e risolte euristicamente. Va notato che tale euristica può cambiare nel tempo, in particolare quando vengono introdotti nuovi schemi di URL. Poiché un URL abbreviato ha la stessa sintassi di un percorso URL relativo, i riferimenti URL abbreviati non possono essere utilizzati in contesti in cui sono previsti gli URL relativi . Ciò limita l'uso di URL abbreviati ai posti in cui non esiste un URL di base definito, ad esempio finestre di dialogo e annunci pubblicitari offline .

Quello che ho capito è che Uri.IsWellFormedUriString accetta stringhe che sono in forma di www.abc.com come URI validi. Ma google.com non è accettato come URI assoluto mentre è accettato come URI relativo perché è conforme alle specifiche relative del percorso (i percorsi possono contenere).

Inoltre, come nota a margine, se si desidera utilizzare un'espressione regolare per analizzare un URI, è possibile leggere B. Analisi di un riferimento URI con un'espressione regolare.

+0

grazie per la risposta. Questo metodo è interessante, convalida "google.com" che è ottimo, tuttavia convalida una singola parola ("google") come un uri ben formato, cosa che non mi serve. Risposta utile comunque –

+0

@Andrei: Ho aggiornato la mia risposta. La risposta si trova in RFC 2396. – Zafer

+0

Grazie per questo, ho letto di più su Uri.IsWellFormedUriString e penso di capire perché convalida "google" come Uri valido. Quindi, quello di cui ho bisogno immagino, è un modo per verificare se alla fine della stringa è collegato un file .com, .net, ..etc. Sono riluttante a usare Regular Exp su questo perché possono avere difetti, e se in futuro qualcuno inventi un'estensione popolare come ".zedo", ad esempio, il mio regExp non lo catturerà poiché gestirà solo terminazioni note (.net, .com ecc.) –

2

utilizzare RegExp per questo.

codice di esempio di URL convalida

Regex RgxUrl = new Regex("(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?"); 
    if (RgxUrl.IsMatch(<yourURLparameter>)) 
    { 
     //url is valid 
    } 
    else 
    { 
     //url is not valid 
    } 
3

che è una variante del codice da Jojaba a che ringrazio per il controllo DNS, che era quello che mi serviva. l'unico problema è che utilizza un tentativo di cattura nella sua logica che speravo di evitare.

 public static Uri StringToAbsoluteUri(string uriString) 
     { 
     Uri resultUri = null; 

     if (!uriString.Contains(Uri.SchemeDelimiter)) 
      uriString = Uri.UriSchemeHttp + Uri.SchemeDelimiter + uriString; 

     if (Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out resultUri)) 
     { 
      try 
      { 
       IPAddress[] addressesOfHost = Dns.GetHostAddresses(resultUri.DnsSafeHost); 
       if (addressesOfHost.Length > 0) 
       { 
        return resultUri; 
       } 
      } 
      catch (System.Net.Sockets.SocketException) 
      { 
       return null; 
      } 
     } 
     return resultUri; 
     }