首先,我想說它沒有這麼好的主意,因爲您可以使用Uri.TryCreate方法來使用異常來檢查有效性。所以你可以重寫你的代碼,而不是依靠哪個異常可以被拋出和捕獲。
因此,更好地改變你的
Uri uri;
try
{
uri = new Uri(item.Value.Uri, href);
}
catch(UriFormatException)
{
continue;
}
到
Uri uri;
if (!Uri.TryCreate(item.Value.Uri, href, out uri)) continue;
但是,這並不全面檢查反正。
至於你的問題,答案相對簡單。你錯了假設畸形:
的mailto:網站管理員[@],某網站管理員
URI是Uniform Resource Identifier所以其basic syntax
{方案名稱}:{層次一部分}? {query}] [#{fragment}]
顯然對您的輸入有效。您以資源的URI與「mailto:」方案結束。
當您嘗試訪問Host屬性時,您認爲資源是Http,但默認情況下使用的「mailto」-scheme解析器無法解析主機組件的原始字符串,從而引發異常。
所以寫支票正確,您必須修改您的代碼位:
Uri uri;
if (!Uri.TryCreate(item.Value.Uri, href, out uri)) continue;
if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) continue;
閱讀UriParser
這裏更新基於@馬克評論的一些信息。
我敢肯定,當我試圖獲得AbsoluteUri屬性時,它會拋出異常。爲什麼會失敗?
您不能通過Scheme檢查,因爲它會是「mailto」。所以這裏快速測試:
var baseUri = new Uri("http://localhost");
const string href = "mailto: webmaster [ @ ] somehost ?webmaster";
Uri uri;
if (!Uri.TryCreate(baseUri,href, out uri))
{
Console.WriteLine("Can't create");
return;
}
if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
{
Console.WriteLine("Wrong scheme");
return;
}
Console.WriteLine("Testing uri: {0}", uri);
它以「錯誤的方案」結束。也許我不正確地理解你?
當您更改HREF到:
const string href = "http: webmaster [ @ ] somehost ?webmaster";
它正確傳遞,自動轉義的URI:
http://localhost/%20webmaster%20%5B%[email protected]%20%5D%20somehost%20?webmaster
也都URI的組成部分將提供給你。
主要的問題我儘量在第一部分如下解釋:
在我看來,你會錯誤地將任何統一資源標識符爲HTTP(S)基於URL,但這是錯誤的。 mailto:[email protected]
或gopher://gopher.hprc.utoronto.ca/
或myreshandler://[email protected]
也是可以被成功解析的有效URI。採取Official IANA-registered schemes
所以
URI構造行爲是正常和正確的看看。
它嘗試驗證傳入的URI爲known schemes:
UriSchemeFile
- 指定URI是一個指針到一個文件。
UriSchemeFtp
- 指定通過文件傳輸協議(FTP)訪問URI。
UriSchemeGopher
- 指定通過Gopher協議訪問URI。
UriSchemeHttp
- 指定URI是通過超文本傳輸協議(HTTP)
UriSchemeHttps
訪問 - 指定URI通過安全超文本傳輸協議(HTTPS)訪問。
UriSchemeMailto
- 指定URI是電子郵件地址並通過簡單網絡郵件協議(SNMP)訪問。
UriSchemeNews
- 指定URI是Internet新聞組並通過網絡新聞傳輸協議(NNTP)訪問。
UriSchemeNntp
- 指定URI是Internet新聞組,並通過在方案是不知道
基本URI解析器使用網絡新聞傳輸協議(NNTP)進行訪問(詳見URI scheme generic syntax)。
Basicly Uri.TryCreate()
和方案的檢查足以讓可以傳遞到.NET的HttpWebRequest例如鏈接。你並不需要檢查它們是否合格或不合格。如果鏈接不好(不是格式正確或不存在),當你嘗試請求它們時,你會得到相應的HttpError。
至於你的例子:
http://www.google.com/search?q=cheesy噗
它通過我的支票,併成爲:
http://www.google.com/search?q=cheesy%20poof
你並不需要檢查它是格式良好還是沒有。只要做基本檢查並嘗試請求。希望能幫助到你。
此外,該字符串的mailto:?站長[@],某網站管理員格式錯誤。我字面上的意思是,該字符串,與笨[s和一切都在它
此字符串是畸形通過意義不合式(因爲含有根據RFC 2396排除的字符),但它仍然可以由於URI方案的一致性通用語法(請檢查使用http創建時如何逃脫),因此可以認爲它是有效的。
Uri.IsWellFormedUriString檢查根據RFC2396 URI一致性 - 統一資源標識符(URI):通用語法http://bit.ly/b83qyw,如2.4.3規定。排除的US-ASCII字符。空間必須在URI中轉義。我也會更新我的答案。 – 2010-10-20 18:02:01