Работа с URI
92C# и .NET --- Сетевое программирование --- Работа с URI
Каждый день мы используем универсальные идентификаторы ресурса (Uniform Resource Identifiers, URI), когда что-то ищем в WWW. URI нужны, чтобы идентифицировать и запросить новый вид ресурса. Используя URI, можно обращаться не только к Web-страницам, но и к FTP-серверу, Web-сервису и локальным файлам.
Вместо URI часто используется термин унифицированный указатель ресурса (Uniform Resource Locator, URL). URI-общий термин, используемый для ссылок на ресурсы. URL - это URI, связанный с такими популярными схемами URI, как http, ftp и mailto. В технической документации термин URL больше не употребляется.
Еще один термин может быть вам уже известен - унифицированное имя ресурса (Uniform Resource Name, URN). URN - это стандартизированный URI, используемый для указания ресурса независимо от его расположения в сети.
Проанализируем части URI, ссылающегося на страницу Web-сайта компании Global Knowledge:
http://www.globalknowledge.net:80/training/generic.asp?pageid=1078&country=DACH
Первая часть URI называется схемой (scheme). Схема определяет пространство имен URI и может сузить синтаксис следующего за схемой выражения. Многие схемы названы по соответствующим протоколам (как http, ftp), которые они используют, но это не является обязательным. В нашем примере идентификатором схемы является http. Ограничитель схемы (// в этом примере) отделяет схему от остальной части URL.
После ограничителя схемы следует имя сервера или IP-адрес в десятичной записи с точками, например www.globalknowledge.net.
За именем сервера или IP-адресом находится номер порта, определяющий соединение с конкретным приложением на сервере. Если номер порта не задан, используется номер порта, устанавливаемый для этого протокола по умолчанию (например, порт 80 для HTTP).
Путь определяет страницу (и каталог) запрошенного ресурса. Он необязательно представляет физический файл на сервере, а может создаваться динамически. В данном случае путь имеет вид /training/generic.asp.
От пути символом ? отделена последняя часть этого URI, называемая запросом (query). В нашем примере запрос определен строкой pageid=1078&country=DACH. Строка запроса может состоять из нескольких компонентов, каждый из которых задает переменную и значение, объединенные символом &. Несколько компонентов запроса могут комбинироваться символом &. Так, в нашем примере первый компонент — pageid=1078 с переменной pageid и значением 1078, а второй компонент - country=DACH.
Разделы внутри ресурса можно отождествить с фрагментами. Фрагменты используются для ссылок на разделы внутри HTML-страницы. В разработке Web-страниц фрагменты также называются закладками (bookmarks). Символ # отделяет идентификатор фрагмента от пути. В URL http;//www.microsoft.com/net/basics/glossary.asp#NETFramework фрагментом является строка #NETFramework.
Если символ # добавлен в строку запроса, то это уже не фрагмент. В URL может присутствовать строка запроса или фрагмент, но не то и другое одновременно.
В URI зарезервировано использование нескольких символов — они не могут входить в имена хостов или путь, поскольку представляют собой специальные символы-разделители. В URI зарезервированы следующие символы:
; / ? : @ & = + $ ,
Класс Uri из пространства имен System инкапсулирует универсальный идентификатор ресурсов. Он содержит свойства и методы для анализа, сравнения и комбинирования URI.
Можно создать объект Uri, передав конструктору строку URI:
Uri baseURI = new Uri("http://professorweb.ru");
Если уже есть базовый объект Uri, можно создать новый URI, комбинируя базовый URI с относительным URI:
Uri baseURI = new Uri("http://professorweb.ru");
Uri newURI = new Uri(baseURI, "my/csharp/web/level2/2_2.php");
Если базовый URI уже содержит путь, он игнорируется. В качестве базы для нового URI берутся лишь схема, порт и имя сервера.
В классе Uri есть несколько статических полей только для чтения, позволяющих получить некоторые широко распространенные схемы:
- Uri.UriSchemeFile
Файловая схема используется для доступа к файлам локально или на совместно используемых сетевых ресурсах, для которых могут применяться имена, соответствующие соглашению об универсальном назначении имен (Universal Naming Convention, UNC).
- Uri.UriSChemeFtp
Протокол FTP со схемой ftp используется для получения файлов с ftp-сервера и, напротив, помещения файлов на ftp-сервер.
- Uri.UriSchemeGopher
Протокол gopher был предшественником HTTP. Он предоставлял возможности иерархического просмотра текстовой информации о содержании, в чем превосходил FTP. Но скоро был заменен протоколом HTTP.
- Uri.UriSchemeHttp, Uri.UriSchemeHttps
Эти две схемы хорошо известны: http и https. Схема https используется для защищенного обмена.
- Uri.UriSchemeMailto
Схема mailto используется для отправки почтовых сообщений.
- Uri.UriSchemeNews, Uri.UriSchemeNntp
Схемы news и nntp применяются в группах новостей, использующих протокол NNTP.
В классе Uri есть статические методы для проверки правильности схемы и имени хоста: Uri.CheckSchemeName() возвращает true, если имя схемы задано правильно, а метод UriCheckHostName() не только проверяет имя хоста, но и возвращает значение перечисления UriHostNameType, указывающее тип хоста.
В классе Uri имеется масса свойств с доступом только на чтение, позволяющих обращаться ко всем частям URI. В следующей таблице используем приведенный выше URI как пример, демонстрирующий применение свойств:
AbsoluteUri | Это свойство показывает полный URI. Если указанный номер порта для протокола равен номеру порта по умолчанию, конструктор Uri автоматически его удаляет. Для нашего примера значение свойства AbsoluteUri выглядит так: http://www.globalknowledge.net/t raining/generic.asp?pageid=1078&country=DACH. Если конструктору класса Uri передается имя файла, свойство AbsoluteUri автоматически помещает перед именем файла схему file://. |
Scheme | Схема — первая часть URI, и в данном случае это свойство возвращает значение http. |
Host | Свойство Host показывает имя хоста из URI: www.globalknowledge.net |
Authority | Если номер порта равен номеру, используемому протоколом по умолчанию, свойство Authority показывает ту же строку, что и свойство Host. Если используется другой номер порта, то свойство Authority также показывает номер порта. |
HostNameType | Тип имени хоста зависит от используемого имени. В данном случае получается то же самое значение перечисления UriHostNameType, которое было рассмотрено выше. |
Port | С помощью свойства Port получается номер порта — 80. |
AbsolutePath | Абсолютный путь начинается после номера порта в URI и заканчивается перед строкой запроса. В этом случае он имеет значение /training/generic.asp. |
LocalPath | Локальный путь дает значение /training/generic.asp. Как можно видеть, для запроса HTTP между AbsolutePath и LocalPath нет никакого различия. Различие появляется, если URI ссылается на совместно используемый сетевой ресурс. Для URI в виде file:\\server\share\directory\file.txt свойство LocalPath возвращает только имена directory и file, а свойство AbsolutePath включает имена server и share. |
Query | Свойство Query показывает строку, следующую после пути: ?pageid=1078&country=DACH. |
PathAndQuery | Свойство PathAndQuery дает комбинацию пути и строки запроса: /training/generic.asp?pageid=1078&country=DACH. |
Fragment | Если после пути следует фрагмент, он возвращается в свойстве Fragment. За путем могут следовать только строка запроса или фрагмент. Фрагмент идентифицируется символом # |
Segments | Свойство Segments возвращает массив строк, сформированный из пути. В данном случае у нас есть три сегмента: /, training/ и generic.asp. |
UserInfo | Установленное в URI имя пользователя можно прочитать из свойства UserInfo. Передача имен пользователей распространена в протоколе FTP, и если указан не анонимный пользователь, например ftp://myuser@ftp.myserver.com, то свойство UserInfo вернет myuser. |
Кроме перечисленных, существует еще несколько свойств, возвращающих булевы значения, если URI представляет файл, путь UNC, адрес обратной связи или если для данного протокола используется номер порта по умолчанию. Это свойства IsFile, IsUnc, IsLoopback и IsDefaultPort соответственно.
После создания конструктором экземпляр класса Uri не может больше изменяться. Свойства класса Uri доступны только на чтение. Для динамического изменения URI можно использовать класс UriBuilder. Его свойства аналогичны свойствам класса Uri, но их значения можно как считывать, так и записывать. Благодаря доступу только на чтение класс Uri гораздо быстрее класса UriBuilder. С такой идеей вы, возможно, знакомы, если работали с классами String и StringBuilder.
В следующем примере передачей конструктору схемы, имени хоста, имени порта и пути создается экземпляр класса UriBuilder. Затем изменим путь, устанавливая свойство Path. Свойство Uri класса UriBuilder возвращает доступный только на чтение экземпляр класса Uri:
UriBuilder myURI = new UriBuilder("http", "professorweb.ru", 80,
"my/csharp/web/level2/2_2.php", "#titlecode");
Uri uri1 = myURI.Uri;