Опыт миграции ASP.NET приложений на IIS 7 и MSSQL 2008

05.04.2010 0:54 / Артём Волк / 4506 просмотров / ...

Возникла необходимость перенести существующие проекты написанные на ASP.NET 2.0 и 3.5SP1 работающие на IIS6 и MSSQL 2005 на актуальные версии компонентов веб-платформы. В IIS6 использовался ASP.NET wildcard mapping поэтому для IIS7 был выбран Integrated Mode.

Сюрпризы IIS Manager

Для удалённого управления конфигурацией IIS7 существует утилита IIS7 Manager. Конечным результатом действий пользователя с интерфейсом этой утилиты обычно являются параметры в файле Web.config соответствующего уровня (IIS7 не использует монолитную метабазу как IIS6, вместо неё используется система конфигурации основанная на каскадном применении конфигурационных XML-файлов). Поэтому, в случае конфигурации на уровне веб-сайта или веб-приложения (а при желании и на корневом уровне) использование утилиты необязательно, аналогичных результатов можно достичь ручным редактированием конфигурационных файлов.

Для работы IIS Manager на Windows XP достаточно иметь установленный .NET Framework 2.0 или выше. Для Windows Vista и 7 кроме .NET Framework'a необходимо наличие Internet Information Services Management Console. Младшие версии этих ОС (до Home Premium) не поддерживают установку этого компонента.

Миграция на MS SQL 2008

Одним из неприятных моментов стало то, что MS SQL Studio Express 2005 не поддерживает подключение к MS SQL 2008, для подключения к новой версии сервера необходимо обновить Studio Express. Утилиты, использующие другие клиентские библиотеки, например SQLDbx или SQL Server Dumper работают с новой версией корректно.

Миграция ASP.NET приложений

Для конфигурирования IIS7 в Integrated Mode используется секция <system.webServer /> файла Web.config. Важно то, что эта секция не поддерживается отладочным веб-сервером из комплекта Visual Studio 2008 (как и IIS6), поэтому в случае использовании этого сервера для разработки и IIS7 для развёртывания, необходимо иметь два комплекта конфигурации секций HttpModules и HttpHandlers.

Пример конфигурации (используется HTTP-модуль для gzip-сжатия страниц, ещё один для URL-rewriting'а, а также HTTP-хендлер для комбинирования и сжатия JavaScript и CSS, на IIS6 был включен ASP.NET wildcard mapping):

<configuration>
	...
	<system.web>
		...
		<httpModules>
			<add name="ModuleRewriter" type="URLRewriter.ModuleRewriter, URLRewriter" />
			<add name="HttpCompressModule" type="DC.Web.HttpCompress.HttpModule,DC.Web.HttpCompress"/>
		</httpModules>
		<httpHandlers>
			<add verb="*" path="js.axd,css.axd" type="DC.Web.HttpCompress.CompressionHandler,DC.Web.HttpCompress"/>
		</httpHandlers>
		...
	</system.web>
	...
</configuration>

Для корректной работы на IIS7 пришлось добавить следующую секцию (с сохранением настроек из предыдущего листинга):

<system.webServer>	
	<!-- 
		Опция позволяет хранить в одном файле конфигурацию для IIS6 и IIS7 
	-->
	<validation validateIntegratedModeConfiguration="false" />

	<!-- Удобно для отладки
		<httpErrors errorMode="Detailed" />
	-->

	<!-- 
		Конструкцию с path="js.axd,css.axd" пришлось разделить на две строчки:
	-->
	<handlers>
	  <add name="CompressionJS" verb="*" path="js.axd" type="DC.Web.HttpCompress.CompressionHandler,DC.Web.HttpCompress" />
	  <add name="CompressionCSS" verb="*" path="css.axd" type="DC.Web.HttpCompress.CompressionHandler,DC.Web.HttpCompress" />
	</handlers>

	<!--		
		Аттрибут runAllManagedModulesForAllRequests позволяет использовать URL-rewriting
	-->
	<modules runAllManagedModulesForAllRequests="True">
		<add name="ModuleRewriter" type="URLRewriter.ModuleRewriter, URLRewriter" />
		<!--		
			Gzip-сжатие включается параметром ниже, модуль для сжатия не нужен
			<add name="HttpCompressModule" type="DC.Web.HttpCompress.HttpModule,DC.Web.HttpCompress"/>	  
		-->
	</modules>

	<!--
		Включение gzip-сжатия средствами веб-сервера для статических и динамических страниц
	-->
	<urlCompression doDynamicCompression="true" doStaticCompression="true" />
</system.webServer>

Ошибка IIS7 500.19

Судя по всему IIS7 применяет более строгие правила валидации файла Web.config. Вот такая конструкция вызывала серверную ошибку 500.19 с малоинформативным сообщением об ошибке. Решение было найдено экспериментально:

Было:

<add key="SiteTitle" value="ООО &laquo;СуперФирма&raquo;"/>

Стало:

<add key="SiteTitle" value="ООО &amp;laquo;СуперФирма&amp;raquo;"/>

Дополнение от 24.08.2010:

Собственные страницы HTTP-ошибок

В IIS6 собственные страницы ошибок конфигурировались через GUI или с помощью редактирования метабазы. В IIS7 это можно сделать в Web.config:

Для статических файлов (которы не выставляют код HTTP-ответа в нужный) можно применить такой подход:

<httpErrors>
	<remove statusCode="403" subStatusCode="-1" />
	<remove statusCode="404" subStatusCode="-1" />
	<error statusCode="404" prefixLanguageFilePath="" path="404.html" responseMode="File" />
	<error statusCode="403" prefixLanguageFilePath="" path="403.html" responseMode="File" />
</httpErrors>

В случае, если страницы ошибок сами выставляют нужный код ответа, то можно сделать так:

<httpErrors>
	<remove statusCode="403" subStatusCode="-1" />
	<remove statusCode="404" subStatusCode="-1" />
	<error statusCode="404" prefixLanguageFilePath="" path="/404.aspx" responseMode="ExecuteURL" />
	<error statusCode="403" prefixLanguageFilePath="" path="/403.aspx" responseMode="ExecuteURL" />
</httpErrors>