2010-09-09 80 views
9

我需要一個Uri驗證方法。因此,像字符串:從字符串驗證Uri

http://www.google.com」, 「www.google.com」, 「google.com」

..must驗證爲的URI。而像「google」這樣的普通字符串也不能作爲Uri的驗證。 要做這個檢查,我使用了兩種方法:UriBuilder和Uri.TryCreate()。

UriBuilder的問題是,我給它的任何字符串,它會返回一個Uri。當我在構造函數中傳遞一個普通字符串時,它會給出一個方案並返回「http://google/」,這不是我想要的行爲。

Uri.TryCreate()的問題在於,雖然它可以與「http://www.google.com」和「www.google.com」正常工作,但當我將其設置爲「google.com」時,它不會驗證是否爲Uri。

我考慮過對字符串進行檢查,如果它以http://或www開頭,則將字符串發送到UriBuilder類,但這對於「google.com」也沒有幫助,它也必須是Uri。

如何驗證諸如「google.com」之類的東西作爲Uri,而不是「google」?檢查.com,.net,.org字符串的結尾似乎不靈活。

+2

您可以驗證您是否正在驗證URL或URI嗎?你的問題有點令人困惑。 – slugster 2010-09-09 07:12:15

+0

@Slugster - 在閱讀完您的問題後,我在網上查詢瞭解差異,所以答案是我需要驗證一個URI而不是URL。 – 2010-09-09 12:14:40

回答

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

該協議可以是除HTTP之外的其他一些內容(http://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Examples_of_absolute_URIs)。 – slugster 2010-09-09 07:04:39

+0

@slugster:這就是爲什麼他會檢查它是否已經有一個協議......他只會將它設置爲http,如果它不是......這是迄今爲止最常見的並且對默認情況非常安全。 – mpen 2010-09-09 07:54:01

+0

謝謝你的代碼。然而,這段代碼從一個單詞構建了一個Uri - 如果我通過「谷歌」,我得到了「http:// google /」,這不是我所需要的。另外我想避免在try/catch結構上構建代碼邏輯。 – 2010-09-09 12:41:23

15

你在找什麼是Uri.IsWellFormedUriString。下面的代碼返回true:

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

如果設置UriKind爲Absolute,則返回false:

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

編輯: 見here爲UriKind枚舉。

  • RelativeOrAbsolute:Uri的類型是不確定的。
  • 絕對:Uri是絕對的Uri。
  • 相對:Uri是相對的Uri。

MSDN documentation

絕對URI的特徵在於一個完整參考資源(例如:http://www.contoso.com/index.html),而相對URI取決於先前定義的基URI(例如:/index.html )。

另外,對於Uri.IsWellFormedUriString,參見here。此方法符合RFC 2396和RFC 2732.

如果您查看RFC 2396,您會看到google.com不是有效的URI。事實上,www.google.com並不是。但下F.縮網址,這situtation進行詳細說明如下:

URL語法是專爲明確的參考網絡 資源和可擴展性通過URL方案。然而,隨着URL 的識別和使用已經變得司空見慣,傳統媒體 (電視,廣播,報紙,廣告牌等)已經越來越多地使用縮寫的URL引用。也就是說,由 組成的參考僅包括所標識的資源的權威和路徑部分,諸如 如 www.w3.org/Addressing/ 或者僅僅是DNS主機名。這樣的參考主要是用於人類解釋而不是機器的 ,其中 假設基於上下文的啓發式就足以完成 的URL(例如,以「www」開頭的大多數主機名可能具有 的URL前綴「http ://「)。雖然沒有標準的 啓發式來區分縮寫的URL引用,但許多客戶端實現允許用戶輸入它們並且啓發式地解析 。應該指出的是,這種啓發式可能會隨着時間的推移而變化,特別是當引入新的URL方案時。 由於縮寫的URL與相對URL路徑具有相同的語法,因此在需要相對 URL的上下文中不能使用縮寫的URL引用。這限制了使用縮略網址的地方 沒有定義的基本URL,如對話框和離線 廣告。

我的理解是,Uri.IsWellFormedUriString接受形式爲www.abc.com的字符串作爲有效的URI。但是google.com不被接受爲絕對URI,而是被接受爲相對URI,因爲它符合相對路徑規範(路徑可以包含。)。另外,作爲一個附註,如果您想使用正則表達式來解析URI,您可以閱讀B.使用正則表達式解析URI引用

+0

謝謝你的回答。這種方法很有趣,它確實驗證了「google.com」,但它驗證了一個單詞(「google」)是一個很好的uri,我也不需要。 – 2010-09-09 12:32:38

+0

@Andrei:我已經更新了我的答案。答案在於RFC 2396. – Zafer 2010-09-09 13:29:07

+0

感謝你們,我進一步閱讀了關於Uri.IsWellFormedUriString的內容,我想我明白爲什麼它將「google」驗證爲有效的Uri。所以,我想我需要的是檢查字符串末尾是否附有.com,.net,..etc的方法。我不願意使用Regular Exp,因爲它們可能存在缺陷,如果將來有人發明了像.zedo這樣的流行擴展,例如我的regExp不會捕獲它,因爲它只能處理已知的終止(.net, .com等)。 – 2010-09-09 16:26:04

2

爲此使用RegExp。驗證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

如此

示例代碼是從Jojaba我向他們感謝的DNS檢查代碼的變種,這是我需要的東西。唯一的問題是它在我希望避免的邏輯中使用try catch。

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