Прежде всего, я хочу сказать, что не очень хорошая идея использовать Exception для проверки действительности, потому что вы можете использовать метод 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: webmaster [@] somehost? Webmaster
URI равен Унифицированный идентификатор ресурса , поэтому его basicсинтаксис
{имя схемы}: {иерархическая часть} [?{query}] [# {фрагмент}]
, очевидно, действительны для вашего ввода.Вы заканчиваете URI ресурса со схемой "mailto:".
Когда вы пытаетесь получить доступ к свойству Host, вы предполагаете, что ресурс был Http, но синтаксический анализатор "mailto", используемый по умолчанию, не может проанализировать исходную строку для хостакомпонент и, следовательно, выдвинутое исключение.
Таким образом, чтобы правильно написать чек, вам нужно немного изменить код:
Uri uri;
if (!Uri.TryCreate(item.Value.Uri, href, out uri)) continue;
if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) continue;
Прочитать некоторую информацию о UriParser
Здесь обновление, основанное на комментариях @Mark.
Я почти уверен, что оно выдало исключение, когда я тоже попытался получить свойство AbsoluteUri ... почему это должно произойти?
Вы не можете пройти проверку Схемы, так как это будет "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%20@%20%5D%20somehost%20?webmaster
также вам будут доступны все компоненты uri.
Основная проблема, которую я пытаюсь объяснить в первой части, следующая:
Кажется,Вы неправильно воспринимаете любой универсальный идентификатор ресурса как URL-адрес на основе http (s), но это неправильно.mailto:webmaster@somehost.tst
или gopher://gopher.hprc.utoronto.ca/
или myreshandler://something@somewhere
также допустимый URI, который может быть успешно проанализирован.Взгляните на Официальные схемы, зарегистрированные IANA
Итак
Ожидается и корректно поведение Uri-конструктора.
пытается проверить входящий URI для известных схем :
UriSchemeFile
- Указывает, что URI является указателем на файл. UriSchemeFtp
- Указывает, что доступ к URI осуществляется через протокол передачи файлов (FTP). UriSchemeGopher
- Указывает, что доступ к URI осуществляется через протокол Gopher. UriSchemeHttp
- Указывает, что доступ к URI осуществляется через протокол передачи гипертекста (HTTP) UriSchemeHttps
- Указывает, чтоДоступ к URI осуществляется через безопасный протокол передачи гипертекста (HTTPS). UriSchemeMailto
- Указывает, что URI является адресом электронной почты и доступ к нему осуществляется через простой сетевой почтовый протокол (SNMP). UriSchemeNews
- Указывает, что URI является новостной группой в Интернете и доступенчерез сетевой транспортный протокол новостей (NNTP). UriSchemeNntp
- Указывает, что URI является новостной группой Интернета и доступ к ней осуществляется через сетевой транспортный протокол новостей (NNTP)
Базовый синтаксический анализатор URI используется, когда схема неизвестна (см. Общий синтаксис схемы URI ).
Обычно Uri.TryCreate()
и проверок схемы достаточно для получения ссылок, которые можно передать, например, в .NET HttpWebRequest.Вам действительно не нужно проверять, правильно ли они сформированы или нет.Если ссылки плохие (плохо сформированы или не существуют), вы просто получаете соответствующий HttpError при попытке их запросить.
Как в вашем примере:
http://www.google.com/search?q=cheesy poof
он проходит мой чек и становится:
http://www.google.com/search?q=cheesy%20poof
Вам не нужно проверять, хорошо ли этоили нет.Просто сделайте базовые проверки и попробуйте запрос.Надеюсь, это поможет.
Кроме того, строка mailto: webmaster [@] somehost? Webmaster неверна. Я буквально имею в виду эту строку, с глупыми [] и всем в ней
Эта строка неправильно сформирована по смыслу не правильно сформирована (поскольку содержит исключенные символы в соответствии с RFC 2396 ), но все равно может рассматриваться как Действительный из-за соответствия универсального синтаксиса схемы URI (проверьте также, как он избежал, когда создан с http:).