Ошибка в конструкторе Uri .NET Framework?

#c# #.net #uri

#c# #.net #uri

Вопрос:

Почему третий relativeURI завершается с ошибкой? Это ошибка .NET? Похоже, что это не исправлено и в 4.0.

 var googleU = new Uri("http://www.google.com");
var secondRelativeUri = new Uri(googleU,"//test.htm"); // doesn't fail
var thirdRelativeUri = new Uri(googleU,"///test.htm"); // fails - Invalid URI: The hostname could not be parsed.
  

Обновить:

@dariom указал, что это связано с обработкой относительных URL-адресов протокола в .NET, что имеет смысл, однако мне это все еще кажется ошибочным:

 var thirdRelativeUri = new Uri("///test.htm",UriKind.Relative); // works as expected
var newUri = new Uri(googleU,thirdRelativeUri); //Fails, same error even though it's a relative URI
  

Сбой происходит даже тогда, когда второй Uri Relative

Комментарии:

1. почему вы передаете «///test.htm «и не»//test.htm «??

2. @DavidePiras потому что я злой? Мне нужно сделать следующий запрос: example.com///test.htm в идеальном мире example.com/test.htm и example.com///test.htm не имеет значения, но реальные веб-серверы и фреймворки, к сожалению, безумны, и их тысячи.

3. Я согласен с @dr.evil. Синтаксический анализ должен принимать бесполезные разделители каталогов / путей.

Ответ №1:

Файл схемы uri файла (RFC 1738) file://[host]/path показывает, что host является необязательным. ///test.html будет означать «Поскольку это обычно используется для локальных файлов, хост из RFC 1738 часто пуст, что приводит к начальной тройке /. (ссылка)»

Изменение ///test.htm для file:///test.htm и конструктор URI проанализирует это должным образом. Это AbsolutePath будет /test.html.

Надеюсь, это поможет.

Ответ №2:

Я думаю, что конструктор интерпретирует «//test.htm « как URI без схемы и имя хоста из test.htm. Вы можете убедиться в этом, изучив значение secondRelativeUri — это «http://test.htm /».

Третий URI, который вы создаете, недопустим, потому что у вас слишком много косых черт.

Комментарии:

1. В качестве дополнительного примечания, URI, начинающиеся с // , называются URI, относительными к протоколу.

2. Хорошо замечено, тем не менее, хотя, когда я явно указываю .net, что это относительный URI, он все равно не работает. Обновил вопрос, добавил новый пример кода.

Ответ №3:

новый Uri(googleU,»//test.htm «) означает Uri = http://test.html / /* допустимо, в любом случае, где-то есть корень */

новый Uri(googleU,»///test.htm «) означает Uri = http:///test.html / /* недопустимый, бессмысленный */

новый Uri(«///test.htm «, ссылка на UriKind.Относительный); //=> Uri = ///test.htm та же ошибка, не относительное расположение

var r = новый Uri(«test.htm «, ссылка на UriKind.Относительный);

новый Uri(googleU, r); // => Uri = http://www.google.com/test.htm

Комментарии:

1. Как это отвечает на вопрос?

Ответ №4:

Даже при создании относительных URL-адресов .net обрабатывает строку, начинающуюся с косой черты tow, как имя хоста, например, в «//example.org/document «. Аналогично, три ошибки приводят к путанице, и генерируется исключение. Если вы уверены, что эти //test.htm и ///test.htm есть пути, тогда вы можете попробовать использовать класс UriBuilder.