2010-09-09 7 views
9

Potrzebuję metody sprawdzania poprawności Uri. Tak, jak struny:Sprawdzanie poprawności URI z łańcucha znaków

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

..must zostać zatwierdzone jako URI. I normalne ciągi takie jak "google" nie mogą być sprawdzane jako Uri. Aby wykonać to sprawdzanie, używam dwóch metod: UriBuilder i Uri.TryCreate().

Problem z UriBuilder polega na tym, że dowolny ciąg, który mu podaję, zwraca z niego Uri. Kiedy przekazuję normalny ciąg w jego konstruktorze, daje on schemat i zwraca "http://google/", co nie jest pożądanym zachowaniem.

Problem z Uri.TryCreate() polega na tym, że gdy działa poprawnie z "http://www.google.com" i "www.google.com", to gdy go podaję "google.com", nie sprawdza się jako Uri.

Myślałem o sprawdzaniu napisu, jeśli zaczyna się od http: // lub www, wyślij ciąg do klasy UriBuilder, ale to nie pomoże w "google.com", które również musi być Uri.

W jaki sposób mogę sprawdzić takie dane, jak "google.com" jako Uri, ale nie "google"? Sprawdzanie końca łańcucha dla .com, .net, .org nie wydaje się elastyczne.

+2

Czy możesz sprawdzić, czy chcesz zweryfikować adres URL lub URI? Twoje pytanie jest nieco mylące. – slugster

+0

@ Slugster - po przeczytaniu Twojego pytania sprawdziłem online, aby zrozumieć różnicę, więc odpowiedź brzmi, że muszę zweryfikować URI, a nie URL. –

Odpowiedz

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

Protokół może być [kilka innych rzeczy] (http://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Examples_of_absolute_URIs) innych niż HTTP. – slugster

+0

@slugster: Właśnie dlatego sprawdza, czy ma już protokół ... ustawia go na http, jeśli nie ma ... który jest zdecydowanie najczęstszy i jest całkiem bezpieczny. – mpen

+0

Dziękujemy za Twój kod. Jednak ten kod buduje URI z jednego słowa - jeśli przekażę "google", otrzymam zwrot "http: // google /", który nie jest tym, czego potrzebuję. Również chciałbym uniknąć budowania logiki kodu na konstrukcjach try/catch. –

15

To, czego szukasz, to Uri.IsWellFormedUriString. Poniższy kod zwraca true:

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

Jeśli ustawisz UriKind do Absolutu, zwraca fałsz:

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

EDIT: Zobacz here dla UriKind wyliczenie.

  • RelativeOrAbsolute: Rodzaj Uri jest nieokreślony.
  • Absolutnie: Uri jest absolutnym Uri.
  • Względny: Uri jest względnym Uri.

Z MSDN documentation:

bezwzględna URI charakteryzuje się w odniesieniu do całkowitego zasobu (np http://www.contoso.com/index.html), podczas gdy względne Uri zależy od uprzednio określonej zasady URI (na przykład: /index.html).

Zobacz również here dla Uri.IsWellFormedUriString. Ta metoda działa zgodnie z dokumentami RFC 2396 i RFC 2732.

Jeśli spojrzysz na RFC 2396, zobaczysz, że google.com nie jest prawidłowym identyfikatorem URI. W rzeczywistości www.google.com nie jest ani. Ale pod F. skróconego URL, to situtation jest szczegółowo opisany w następujący sposób:

Składnia URL został zaprojektowany do jednoznacznego odnośnika na sieciowy zasobów i rozciągliwości poprzez schematu URL.Ponieważ jednak identyfikacja i korzystanie z adresu URL stały się powszechne, tradycyjne media (telewizja, radio, gazety, billboardy itp.) Mają coraz częściej używane skrócone adresy URL. To jest odniesienie składające się z tylko część autoryzacji i ścieżek zidentyfikowanego zasobu, na przykład jako po prostu sama nazwa DNS serwera DNS. Takie odniesienia są głównie przeznaczone do ludzkiej interpretacji, a nie maszyny, z założeniem, że heurystyka oparta na kontekście jest wystarczająca do wypełnienia adresu URL (np. Większość nazw hostów zaczynających się od "www" prawdopodobnie będzie mieć przedrostek adresu URL "http" : // "). Chociaż nie ma standardowego zestawu heurystyk odznaczających jednoznaczne skrócone adresy URL, wiele implementacji klienta umożliwia ich wprowadzenie przez użytkownika i analizę heurystyczną. Należy zauważyć, że takie zmiany heurystyczne mogą z czasem ulec zmianie, szczególnie w przypadku wprowadzania nowych schematów adresów URL. Skrócony adres URL ma tę samą składnię co ścieżka względnego adresu URL, dlatego skróconych adresów URL nie można używać w kontekstach, w których spodziewane są względne adresy URL: . Ogranicza to użycie skróconych adresów URL do miejsc , w których nie ma zdefiniowanego podstawowego adresu URL, takiego jak okna dialogowe i reklamy off-line .

Rozumiem z tego, że Uri.IsWellFormedUriString przyjmuje ciągi, które są w formie www.abc.com jako poprawne identyfikatory URI. Ale google.com nie jest akceptowany jako bezwzględny URI, podczas gdy jest akceptowany jako względny URI, ponieważ jest zgodny ze specyfikacją ścieżki względnej (ścieżki mogą zawierać.).

Również, na marginesie, jeśli chcesz użyć wyrażeń regularnych do analizy identyfikatora URI, możesz przeczytać B. Analizowanie odniesienia URI za pomocą wyrażenia regularnego.

+0

dziękuję za odpowiedź. Ta metoda jest interesująca, sprawdza poprawność "google.com", ale sprawdza ona jedno słowo ("google") jako dobrze uri, którego nie potrzebuję. Pomocna odpowiedź jednak: –

+0

@Andrei: Zaktualizowałem moją odpowiedź. Odpowiedź leży w RFC 2396. – Zafer

+0

Dziękuję za to, mam dalej przeczytać o Uri.IsWellFormedUriString i myślę, że rozumiem, dlaczego to potwierdza "google" jako prawidłowy Uri. Potrzebuję więc, aby sprawdzić, czy koniec łańcucha ma dołączoną stronę .com, .net, ..etc. Nie chcę używać Regular Exp, ponieważ mogą one mieć wady, a jeśli w przyszłości ktoś wymyśli popularne rozszerzenie, na przykład ".zedo", to mój regExp go nie złapie, ponieważ zajmie się tylko znanymi zakończeniami (.net, .com itp.). –

2

użyj RegExp do tego.

Przykładowy kod walidacji URL

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

jest to wariant kodu z Jojaba, któremu dziękuję za sprawdzania DNS, to było to, czego potrzebowałem. Jedyny problem polega na tym, że używa próby catch w swojej logice, której miałem nadzieję uniknąć.

 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; 
     } 
Powiązane problemy