Разработка модулей и обработчиков IIS 7.0 с помощью платформа .NET Framework
Общие сведения
Эта статья посвящена началу разработки функций веб-сервера IIS 7.0 и более поздних версий на основе платформа .NET Framework. В этой статье показано следующее:
- Как решить, следует ли разрабатывать модуль IIS или обработчик IIS
- Настройка среды разработки с помощью Visual Studio, Visual C# Express или программ командной строки, предоставляемых в платформа .NET Framework
- Создание первого проекта
- Разработка простого модуля и обработчика
- Развертывание простого модуля и обработчика на сервере IIS
Чтобы просмотреть некоторые реальные управляемые модули и обработчики IIS и скачать их для приложения, см. статьи Перенаправление запросов к приложению с помощью модуля HttpRedirection, Получение красивых списков каталогов для веб-сайта IIS с помощью DirectoryListingModule и Отображение красивых значков файлов в приложениях ASP.NET с помощью IconHandler.
Введение. Разработка функций IIS с помощью ASP.NET
В выпусках IIS, предшествующих IIS 7.0, в качестве основного API расширяемости для создания функций веб-сервера был представлен API C, называемый ISAPI. СЛУЖБЫ IIS 7.0 и более поздних версий были реконструированы с нуля, чтобы обеспечить совершенно новый API C++, на котором основаны все встроенные функции, чтобы обеспечить полную расширяемость веб-сервера во время выполнения.
Кроме того, СЛУЖБЫ IIS впервые также предоставляют полный api .NET для расширения веб-сервера, используя тесную интеграцию с ASP.NET 2.0. Для вас это означает, что теперь вы можете расширить службы IIS с помощью новых функций веб-сервера, созданных с помощью знакомых API ASP.NET 2.0. Аналогичным образом можно использовать существующие модули и обработчики ASP.NET 2.0 в IIS, используя интеграцию ASP.NET, чтобы расширить возможности приложения без написания нового кода. Дополнительные сведения об интеграции ASP.NET в IIS см. в статье Интеграция ASP.NET с IIS 7.
Инструменты торговли: выбор среды разработки
Для создания модулей и обработчиков IIS используйте любую среду, которая позволяет разрабатывать и компилировать сборки .NET. Ниже приведены некоторые распространенные варианты.
- Visual Studio 2005. Кроме того, можно скачать последнюю бета-версию Visual Studio 2008.
- Бесплатный выпуск Visual C# 2005 Express (или другие средства Express, включая Visual Basic 2005 Express).
- Компилятор командной строки C# (csc.exe), включенный в среду выполнения .NET Framework (для других языков вам потребуется скачать пакет SDK), а также любимый редактор исходного кода.
В примерах в этой статье используется C#, хотя вы можете разрабатывать компоненты IIS на любом другом поддерживаемом языке .NET (кроме управляемого C++). В этой статье показано, как разрабатывать компоненты расширяемости IIS для всех трех указанных выше сред.
Примечание
Так как службы IIS используют существующие API ASP.NET для расширения .NET, вы можете разрабатывать модули и обработчики IIS .NET с помощью платформа .NET Framework 2.0 в Windows XP® и Windows Server® 2003. Однако если вы планируете использовать один из нескольких новых API-интерфейсов ASP.NET, добавленных для поддержки новых функций IIS, необходимо либо разработать в Windows Vista®, либо получить версию System.Web.dll в Windows Vista или в последнем выпуске платформа .NET Framework 3.5, чтобы скомпилировать код.
Два способа расширения IIS: модуль и обработчик
Все функции веб-сервера IIS делятся на две категории: модули и обработчики.
Модуль, аналогичный фильтру ISAPI в предыдущих версиях IIS, участвует в обработке каждого запроса, чтобы каким-либо образом изменить или добавить в него. Примерами некоторых встроенных модулей в IIS являются модули проверки подлинности, которые управляют состоянием проверки подлинности запроса, модули сжатия, которые сжимают исходящий ответ, и модули ведения журнала, которые регистрируют сведения о запросе в журналы запросов.
Модуль является классом .NET, который реализует интерфейс ASP.NET System.Web.IHttpModule и использует API в пространстве имен System.Web для участия в одном или нескольких asp. Этапы обработки запросов NET.
Обработчик, аналогичный расширению ISAPI в предыдущих версиях IIS, отвечает за обработку запроса и создание ответа для определенных типов контента. Main разница между модулем и обработчиком заключается в том, что обработчик обычно сопоставляется с определенным путем запроса или расширением и поддерживает обработку определенного ресурса сервера, которому соответствует этот путь или расширение. Примеры обработчиков, предоставляемых службами IIS, включают ASP, который обрабатывает сценарии ASP, обработчик статических файлов, который обслуживает статические файлы, и ASP. Net PageHandler, который обрабатывает страницы ASPX.
Обработчик — это класс .NET, который реализует интерфейс ASP.NET System.Web.IHttpHandler или System.Web.IHttpAsyncHandler и использует API в пространстве имен System.Web для создания http-ответа для определенного содержимого, которое он поддерживает.
При планировании разработки компонента IIS следует задать первый вопрос: отвечает ли эта функция за обслуживание запросов к определенному URL-адресу или расширению или применяется ко всем или некоторым запросам на основе произвольных правил. В первом случае вы должны быть обработчиком, а во втором — модулем.
В этой статье демонстрируется создание простого модуля и простого обработчика, общие шаги по созданию проекта и его компиляции, а также конкретные шаги по их развертыванию на сервере.
Примечание
Вам не нужно разрабатывать обработчик, если вы разрабатываете модуль, и наоборот.
начало работы: создание проекта Visual Studio
Чтобы создать модуль или обработчик, необходимо создать сборку .NET (DLL), содержащую классы module/handler. Если вы используете Visual Studio или средства Visual Studio Express, первым шагом является создание проекта библиотеки классов:
В меню "Файл" выберите "Создать", "Проект ...". В диалоговом окне Новый проект (ниже) выберите тип проекта "Visual C#" и выберите "Библиотека классов" в списке установленных шаблонов Visual Studio справа.
Необходимо добавить ссылку на сборку "System.Web.dll", которая содержит API, используемые для разработки модулей и обработчиков ASP.NET и IIS. Щелкните правой кнопкой мыши узел "Ссылки" в узле Проект в представлении дерева обозревателя решений справа, выберите "Добавить ссылку..." и на вкладке .NET выберите сборку System.Web версии 2.0 (ниже).
Примечание
Вы можете использовать сборку System.Web версии 2.0 в Windows XP и Windows Server 2003, если вы не планируете использовать api ASP.NET iis. Модули и обработчики, скомпилированные со ссылкой на эту сборку, можно развертывать и использовать в службах IIS в Windows Vista и Windows Server 2008 без проблем. Если вы хотите использовать несколько API-интерфейсов ASP.NET iis в модуле, необходимо выполнить разработку в Windows Vista, Windows Server 2008 или получить сборку System.Web.dll из платформа .NET Framework 3.5. К api-интерфейсам IIS относятся HttpServerUtility.TransferRequest, коллекция HttpResponse.Headers, событие HttpApplication.LogRequest и ряд других.
Написание кода: создание простого модуля
Первая задача — создать простой модуль. Далее в этой статье мы также создадим пример обработчика.
Чтобы создать модуль, определите класс, реализующий интерфейс System.Web.IHttpModule .
Удалите файл class1.cs, созданный системой проектов, и добавьте новый класс C# с именем MyModule, щелкнув правой кнопкой мыши проект MyIIS7Project в представлении дерева справа, выбрав "Добавить", "Новый элемент", выбрав "Класс" и введя "MyModule.cs" в поле Имя.
Импортируйте пространство имен System.Web , чтобы мы могли легко получить доступ к его типам.
Класс MyModule реализует интерфейс IHttpModule и определяет члены интерфейса Dispose() и Init(). Чтобы быстро сделать это, щелкните правой кнопкой мыши интерфейс IHttpModule и выберите параметр "Реализовать интерфейс".
Метод Dispose() предназначен для детерминированной очистки всех неуправляемых ресурсов при выгрузке модуля, чтобы ресурсы можно было освободить до завершения экземпляра модуля сборщиком мусора. Этот метод можно оставить пустым большую часть времени.
Метод Init(контекст HttpApplication) является main интересующим методом. Его роль заключается в выполнении инициализации модуля и подключении модуля к одному или нескольким событиям обработки запросов, доступным в классе HttpApplication . Во время обработки запроса модуль будет вызываться для каждого события, на которое он подписан, что позволяет ему выполнять и выполнять обслуживание. Для этого выполните указанные далее действия.
Подпишитесь на одно или несколько событий обработки запросов, проводя метод в классе модуля с одним из событий в предоставленном экземпляре HttpApplication. Метод должен следовать подписи делегата System.EventHandler . Мы определяем новый метод с именем OnPreExecuteRequestHandler и привязаем его к httpApplication. Событие PreRequestRequestHandlerExecute , которое происходит непосредственно перед вызовом сервера обработчика запроса:
public void Init(HttpApplication context) { context.PreRequestHandlerExecute += newEventHandler(OnPreRequestHandlerExecute) }
На этом этапе наш модуль настроен для получения события PreRequestHandlerExecute при каждом запросе. Это можно повторить для всех других событий, которые вы хотите получить.
Теперь мы делаем наши модули полезными, иллюстрирует использование некоторых api ASP.NET, которые может использовать модуль. Проверьте, указывает ли запрос заголовок ссылок, и, если он делает, отклоните его, как глупый способ запретить пользователям ссылаться на ваш веб-сайт с других веб-сайтов. Мы будем делать это в нашем методе OnPreRequestHandlerExecute, который вызывается непосредственно перед запуском обработчика для каждого запроса:
public void OnPreRequestHandlerExecute ( Object source, EventArgs e) { HttpApplication app = (HttpApplication)source; HttpRequest request = app.Context.Request; if (!String.IsNullOrEmpty( request.Headers["Referer"] )) { throw new HttpException(403, "Uh-uh!"); } }
Примечание
Экземпляр HttpApplication предоставляется модулю с помощью исходного аргумента и требует приведения. Доступ к остальной части объектной модели запроса можно получить из экземпляра HttpApplication, например объекта HttpContext и содержащегося объекта HttpRequest, представляющего запрос.
Приведенный выше код проверяет, указан ли заголовок Referrer, и если да, он отклоняет запрос с кодом ошибки 403 Unauthorized.
Написание кода: создание простого обработчика
Следующая задача — создать простой обработчик. Ранее в этой статье мы создали пример модуля . Вернитесь назад, если вы хотите прочитать о создании модуля.
Чтобы создать обработчик, необходимо определить класс, реализующий интерфейс System.Web.IHttpHandler (мы также можем реализовать System.Web.IHttpAsyncHandler , если страница должна выполняться асинхронно). Для этого выполните указанные далее действия.
Если вы еще не сделали этого, удалите файл class1.cs, созданный системой проектов, и добавьте новый класс C# с именем MyHandler, щелкнув правой кнопкой мыши проект MyIIS7Project в представлении дерева справа, выбрав "Добавить", "Новый элемент", выбрав "Класс" и введя "MyHandler.cs" в поле Имя.
Импортируйте пространство имен System.Web , чтобы мы могли легко получить доступ к его типам.
Класс MyHandler реализует интерфейс IHttpHandler и определяет члены интерфейса IsReusable и ProcessRequest(). Это можно сделать быстро, щелкнув правой кнопкой мыши интерфейс IHttpHandler и выбрав параметр "Реализовать интерфейс".
IsReusable () указывает, можно ли повторно использовать экземпляр обработчика для последующих запросов. В некоторых случаях после обработки запроса обработчик может оказаться в неправильном состоянии для обработки другого запроса, особенно если вы сохранили данные о предыдущем запросе в переменных-членах. Обратите внимание, что среда выполнения никогда не будет использовать один и тот же экземпляр обработчика для одновременной обработки двух запросов, даже если он помечен как повторно используемый. Если обработчик не сохраняет состояние для каждого запроса в переменных-членах и может вызывать функцию ProcessRequest столько раз, сколько необходимо, сделайте это свойство возвращаемым значением true, чтобы разрешить повторное использование.
Метод ProcessRequest () является main точкой входа обработчика. Его роль заключается в обработке запроса, указанного экземпляром HttpRequest , доступным в предоставленном экземпляре HttpContext , и создании соответствующего ответа с помощью экземпляра HttpResponse , также доступного вне httpContext. Метод ProcessRequest() будет вызываться средой выполнения на этапе обработки запроса ExecuteRequestHandler и только в том случае, если запрос сопоставлен с обработчиком на основе настроенных сопоставлений обработчика. Это отличается от модуля, который получает уведомления для всех запросов к приложению.
Сначала реализуйте свойство IsReusable . Так как наш обработчик не будет хранить состояние участника для запроса и сможет поддерживать несколько вызовов ProcessRequest() с разными запросами, мы помечаем его как пригодный для повторного использования, возвращая значение true.
public bool IsReusable { get { return true; }
Наконец, давайте реализуем метод ProcessRequest(), чтобы сделать обработчик действительно полезным. Чтобы все было хорошо и просто, наш обработчик вернет текущее время на сервере, при необходимости позволяя указать часовой пояс в строке запроса. Наша цель — запросить URL-адрес, например
http://myserver/time.tm
, и получить текущее время на сервере. Кроме того, мы сможем получить универсальное скоординированное время, запросивhttp://myserver/time.tm?utc=true
. Вот наша реализация:public void ProcessRequest(HttpContext context) { DateTime dt; String useUtc = context.Request.QueryString["utc"]; if (!String.IsNullOrEmpty(useUtc) && useUtc.Equals("true")) { dt = DateTime.UtcNow; } else { dt = DateTime.Now; } context.Response.Write( String.Format( "<h1>{0}</h1>", dt.ToLongTimeString() ) ); }
Мы используем коллекцию HttpRequest.QueryString для получения переменной QueryString и записываем текущее время ответа с помощью метода HttpResponse.Write . Это просто пример того, что можно сделать в обработчике. Класс HttpRequest предоставляет гораздо больше сведений о запросе, а класс HttpResponse предоставляет несколько различных способов формирования ответа, возвращаемого клиенту.
Обработчик завершен.
Код завершен: компиляция модуля или обработчика
Теперь, когда мы реализовали модуль и обработчик, можно скомпилировать их в сборку, которую ASP.NET может загружать во время выполнения. Если вы используете Visual Studio или Visual Studio Express, скомпилируйте проект непосредственно из средства, нажав клавиши CTRL+SHIFT+B или щелкнув проект правой кнопкой мыши и выбрав пункт "Сборка".
Сборка .DLL будет создана в папке <ProjectDirectory>\bin\debug вместе с . Файл символов PDB, который можно использовать для отладки сборки на сервере, включая строки исходного кода в исключениях на этапе отладки проекта.
Если вы отправляете сборку на рабочий сервер, обязательно измените конфигурацию решения на "Выпуск", щелкнув правой кнопкой мыши узел решения, выбрав Configuration Manager и изменив тип на Отладка. Отправьте версию выпуска сборки (оставьте PDB-файл позади) — это позволит удалить отладочную информацию из сборки и оптимизировать ее, что приведет к ускорению кода.
Если вы не используете Visual Studio, скомпилируйте проект с помощью компилятора командной строки C#, включенного в среду выполнения Платформы. Чтобы скомпилировать проект, откройте командную строку (обязательно запустите командную строку с параметром "Запуск от имени администратора", если вы используете Windows Vista или Windows Server 2008):
> %windir%\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /out:MyIIS7Project.dll /debug \*.cs /r:System.Web.dll
При этом будут создаваться файлы MyIIS7Project.DLL и MyIIS7Project.PDB. Если вы хотите создать версию выпуска сборки, опустите параметр /debug и включите параметр /o для оптимизации сборки.
Развертывание сборки на сервере
Теперь, когда мы реализовали пользовательский модуль и обработчик, мы развертываем их в веб-приложении. Существует несколько способов развертывания модуля или обработчика в приложении, а также ряд параметров конфигурации, которые можно использовать для адаптации их развертывания к вашим потребностям. Ниже приведены основные шаги по развертыванию. Дополнительные сведения о вариантах развертывания и конфигурации, включая развертывание модуля или обработчика для всего сервера, см. в следующей статье серии: Развертывание модулей и обработчиков IIS (ожидается в ближайшее время).
В приведенных ниже шагах предполагается, что вы развертываете модуль и обработчик в существующем приложении на сервере IIS. Если приложение не создано, используйте корневое приложение веб-сайта по умолчанию, обычно расположенного по адресу %systemdrive%\inetpub\wwwroot
. В приведенном ниже примере мы развертываем модуль и обработчик в приложении myiis7project, расположенном на веб-сайте по умолчанию.
Чтобы развернуть модуль и обработчик, сначала сделайте сборку, содержащую их реализацию, доступной для приложения ASP.NET:
Скопируйте сборкуMyIIS7Project.dll , скомпилированную ранее, в каталог /BIN, расположенный в корне приложения. Если этот каталог не существует, создайте его.
Настройте модуль и обработчик для загрузки в приложение. Откройте средство администрирования IIS7 в меню Пуск, введя inetmgr.exe в поле запуска или поиска и нажав клавишу ВВОД. В средстве дважды щелкните узел сервера в представлении дерева слева, затем разверните узел "Сайты" и дважды щелкните сайт или приложение, в которое вы хотите добавить модуль и обработчик.
Щелкните значок компонента "Модули", затем щелкните действие "Добавить управляемый модуль..." и в открывшемся диалоговом окне введите имя модуля (произвольное) и полный тип модуля MyIIS7Modules.MyModules. Обратите внимание, что вы также можете выбрать тип в раскрывающемся списке, так как средство автоматически загрузит сборку в bin и обнаружит типы, реализующие интерфейс IHttpModule. Нажмите кнопку ОК, чтобы добавить модуль.
Добавьте обработчик, дважды щелкнув узел сайта или приложения и выбрав значок компонента "Сопоставления обработчиков". Затем щелкните действие "Добавить управляемый обработчик" и в открывшемся диалоговом окне укажите "time.tm" в поле пути, "MyIIS7Modules.MyHandler" для типа и "MyHandler" в поле имя (произвольное). Опять же, обратите внимание, что тип присутствует в раскрывающемся списке, так как средство Администратор автоматически обнаружило этот тип в вашей сборке. Нажмите кнопку ОК, чтобы добавить обработчик.
Конфигурация приложения, созданная приведенными выше действиями, настраивает модуль MyModule для загрузки в приложение (что позволяет выполнять его для всех запросов) и сопоставляет обработчик MyHandler для обработки запросов с URL-адресом time.tm в приложении.
Обратите внимание, что эта конфигурация позволяет запускать модуль и приложение только в приложениях в режиме интеграции IIS. Если вы хотите, чтобы модуль и обработчик также запускались в приложениях в классическом режиме в IIS, а также в более ранних версиях IIS, необходимо также добавить конфигурацию классического ASP.NET для модуля и обработчика. Кроме того, при выполнении в классическом режиме в IIS или более ранних версиях IIS обработчик требует создать сопоставление скрипта, сопоставляющее расширение .tm с ASP.NET в картах сценариев IIS, а модуль запускается только для запросов к расширениям, сопоставленным с ASP.NET. Дополнительные сведения об этом см. в разделе Развертывание модулей и обработчиков IIS (ожидается в ближайшее время).
Вы также можете добавить модуль и обработчик с помощью программы командной строки IIS ,AppCmd.exe, либо путем управления конфигурацией IIS из скрипта или управляемого кода, либо путем размещения конфигурации непосредственно в файл web.config . Эти дополнительные параметры подробно рассматриваются в статье Развертывание модулей и обработчиков IIS (ожидается в ближайшее время).
Тестирование модуля и обработчика
Мы развернули и настроили модуль или обработчик. Теперь, чтобы протестировать их:
Протестируйте обработчик, выполнив запрос на time.tm в приложении. В случае успешного выполнения мы видим текущее время на сервере. Сделайте запрос к приложению, например
http://localhost/myiis7project/time.tm
, когда мы развернули обработчик в приложении myiis7project на веб-сайте по умолчанию:Если обработчик правильно развернут в этом приложении, на сервере отображается текущее время:
Также попробуйте запросить
http://localhost/myiis7project/time.tm?utc=true
отображение времени в формате UTC.Протестируйте модуль. Создайте в приложении простую HTML-страницу с именемpage.html , которая ссылается на URL-адрес /time.tm :
page.html
<html> <body> <a href="time.tm">View current server time</a> </body> </html>
Затем отправьте запрос на
http://localhost/myiis7project/page.html
отображение ссылки. При переходе по ссылке отображается сообщение об ошибке:Вы можете спросить, не запросили ли мы этот же URL-адрес выше и успешно ли просмотреть время. Это связано с тем, что наш модуль настроен так, чтобы отклонять запросы к вашему приложению, указывающие заголовок "Ссылка", который добавляется браузером всякий раз, когда пользователь щелкает ссылку для перехода на веб-сайт, а не просто вводит URL-адрес непосредственно в браузере. Таким образом, когда вы запросили URL-адрес напрямую, вы могли получить к нему доступ, но при переходе по ссылке с другой страницы ваш запрос был отклонен нашим модулем.
Итоги
В этой статье мы проиллюстрировали основные шаги по разработке модуля и обработчика IIS с помощью знакомых API ASP.NET и их развертыванию в приложении. Мы также рассмотрели варианты, доступные для вашей среды разработки, а также о том, как решить, когда следует создать модуль или обработчик. Сведения, приведенные в этой статье, должны позволить вам создать первые модули и обработчики для расширения возможностей приложений IIS.
Вы также можете ознакомиться с примером модуля, который включает обычную проверку подлинности в ASP. Поставщики членства NET при разработке модуля с помощью .NET.
Обязательно проверка дополнительные примеры того, как управляемые модули и обработчики IIS могут повысить ценность ваших приложений, и скачайте их для вашего приложения, перейдя в раздел Перенаправление запросов к приложению с помощью модуля HttpRedirection, Получение красивых списков каталогов для веб-сайта IIS с помощью DirectoryListingModule и Отображение значков красивых файлов в приложениях ASP.NET с помощью IconHandler.