ASP.NET MVC 4

ASP.NET MVC 4

Адам Фриман

Подготовка приложения для публикации

Мы собираемся развернуть приложение SportsStore, которое создали в первой части этой книги. Мы выбрали SportsStore, потому что оно использует базу данных, а настройка и проверка работы базы данных является важной частью любого процесса развертывания.

Подсказка

Когда мы говорим о развертывании приложения SportsStore, мы имеем в виду проект SportsStore.WebUI. Нам не нужно отдельно развертывать два других проекта, которые мы создали вместе с ним. Вывод проекта SportsStore.Domain включен в проект WebUI, а модульные тесты из проекта SportsStore.UnitTests не потребуются в рабочем приложении.

Выявляем ошибки представлений

Как мы уже объяснили в главе 18, представления Razor компилируются сервером при запуске приложения, а не когда мы создаем проект в Visual Studio. Как правило, единственный способ обнаружить ошибки компилятора - это систематически обращаться к каждому действию и визуализировать каждое представление. Это утомительная и не всегда успешная техника, особенно если в зависимости от состояния модели визуализируются разные представления.

В проекте можно активировать специальную опцию, которая будет компилировать наши представления и сообщать об ошибках компиляции. Эту функцию нельзя активировать из Visual Studio; откройте файл SportsStore/WebUI/SportsStore.WebUI.csproj в блокноте. Найдите элемент MvcBuildViews и измените его значение на true, как показано в листинге 26-1.

Листинг 26-1: Активируем опцию MvcBuildViews
...
	<PropertyGroup>
		... other settings omitted ...
		<MvcBuildViews>true</MvcBuildViews>
		... other settings omitted ...
	</PropertyGroup>
...

Сохраните изменения и вернитесь в Visual Studio, которая предложит вам перезагрузить проект. Теперь, когда вы скомпилируете проект, Visual Studio скомпилирует файлы представлений и сообщит об ошибках. Чтобы продемонстрировать, как это работает, мы добавили ошибку в представление /Views/Product/List.cshtml, как показано в листинге 26-2.

Листинг 26-2: Добавляем ошибку в файл представления
@model SportsStore.WebUI.Models.ProductsListViewModel
@{
	ViewBag.Title = "Products";
}

@Model.NotARealProperty

@foreach (var p in Model.Products)
{
	Html.RenderPartial("ProductSummary", p);
}

<div class="pager">
	@Html.PageLinks(Model.PagingInfo, 
		x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))
</div>

Как правило, наша попытка визуализировать свойство не будет отображаться, пока мы не запустим приложение и перейдем по ссылке, которая визуализирует представление List.cshtml. Но, когда опция MvcBuildViewsактивирована, мы увидим сообщение об ошибке во время работы над проектом, как показано на рисунке 26-1.

Рисунок 26-1: Ошибка компилятора из-за проблем в представлении

Эта техника позволяет обнаруживать только ошибки компилятора. Она не видит логических ошибок и не может заменить полноценное тестирование, но в качестве предосторожности ее полезно применять перед развертыванием приложения. Мы не сможем развернуть приложение с ошибкой в представлении, так что мы восстановили его до прежнего состояния, как показано в листинге 26-3.

Листинг 26-3: Удаляем ошибку из представления List.cshtml
@model SportsStore.WebUI.Models.ProductsListViewModel

@{
	ViewBag.Title = "Products";
}

@foreach (var p in Model.Products)
{
	Html.RenderPartial("ProductSummary", p);
}

<div class="pager">
	@Html.PageLinks(Model.PagingInfo, x => Url.Action("List",
		new { page = x, category = Model.CurrentCategory }))
</div>

Подсказка

Вы можете увидеть сообщение о том, что будет ошибкой будет использовать секцию, которая зарегистрирована как allowDefinition='MachineToApplication' вне уровня приложения. Это ошибка, которая возникает после развертывания приложения. Мы нашли только одно надежное решение для этой проблемы: очистить проект в режиме отладки, затем в режиме релиза, а затем построить приложение в режиме отладки.

Дезактивируем режим отладки

Одним из наиболее важных элементов в файле Web.config, на который вы должны обратить внимание при развертывании приложения, является compilation, как показано в листинге 26-4.

Листинг 26-4: Элемент compilation в Web.config
<system.web>
	<httpRuntime targetFramework="4.5" />
	<compilation debug="true" targetFramework="4.5" />
	<authentication mode="Forms">
		<forms loginUrl="~/Account/Login" timeout="2880">

Когда атрибут debug содержит значение true, поведение компилятора и приложения будет ориентировано на процесс разработки. Например, компилятор будет выполнять следующие действия:

  • Опускает некоторые процедуры оптимизации кода, чтобы он мог построчно выполнять код.
  • Компилирует каждое представление по запросу, вместо компиляции всех представлений в один прием.
  • Отключает лимит времени запроса, чтобы мы могли провести много времени в отладчике.
  • Ограничивает способы кэширования контента браузерами.

Кроме того, если вы использовали связки для группировки одновременно и CSS, и JavaScript файлов, браузер получит инструкцию загружать каждый файл по отдельности, и он не получит минимизированные версии этих файлов. (Мы рассмотрели связки в главе 24).

Все эти функции полезны при разработке приложения, но они станут помехой при развертывании. Как вы можете догадаться, решение заключается в изменении значения атрибута debug на false:

<compilation debug="false" targetFramework="4.5" />

Чаще всего вам не придется выполнять это изменение перед развертыванием, поскольку изменить конфигурацию приложения можно в утилитах развертывания Visual Studio, или значение в файле Web.config будет переопределено конфигурацией сервера приложений IIS.

Тем не менее, если поведение приложения меняется, когда атрибут debug имеет значение false, то после отключения режима отладки необходимо запустить программу тестирования до того, как выполнять развертывание. Вы должны убедиться, что ваши представления визуализируются так, как вы и планировали, и все связки, использующие маркер {version}, указывают на файлы, которые существуют и доступны на сервере.

Удаляем неиспользуемые строки подключения

Чаще всего в процессе развертывания ошибки возникают при настройке соединения с базой данных. Как мы знаем из своего опыта, большинство проблем возникают из-за информации о неиспользуемых базах данных в файлеWeb.config.

Зная, что базы данных проблематичны, разработчики утилит развертывания пытаются автоматизировать процесс настройки баз данных, но они зациклены на конфигурации по умолчанию, которую добавляет в проект Visual Studio. Чтобы избежать этих проблем, можно отредактировать файл Web.config. В листинге 26-5 показаны два варианта настройки соединения для передачи данных в файле Web.config в проекте SportsStore.WebUI. Запись, в которой атрибут name содержит DefaultConnection, была создана Visual Studio; она помогает запустить новый проект, и мы не используем ее в приложении SportsStore. Другую запись - EFDbContext - создали и использовали мы, и она потребуется в развернутом проекте.

Листинг 26-5: Строки подключения в файле Web.config
<configuration>
	<configSections>
		<section name="entityFramework"
			type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
	</configSections>
	<connectionStrings>
		<add name="DefaultConnection" 
			providerName="System.Data.SqlClient"
			connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-SportsStore.WebUI-20121003232522;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-SportsStore.WebUI-20121003232522.mdf" />
		<add name="EFDbContext" 
			connectionString="Data Source=(localdb)\v11.0;Initial Catalog=SportsStore;Integrated Security=True"
			providerName="System.Data.SqlClient"/>
	</connectionStrings>

Вы можете просто закомментировать ненужные соединения, но мы предпочитаем вносить более определенные изменения, потому что мы провели много часов за отладкой проблем развертывания, возникших из-за информации о неиспользуемых подключениях. В листинге 26-6 показано, как мы отредактировали файл Web.config, оставив только запись в EFDbContext.

Листинг 26-6: Удаляем информацию о неиспользуемых подключениях
<configuration>
	<configSections>
		<section name="entityFramework"
			type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
			requirePermission="false" />
	</configSections>
	<connectionStrings>
		<add name="EFDbContext" 
			connectionString="Data Source=(localdb)\v11.0;Initial Catalog=SportsStore;Integrated Security=True"
			providerName="System.Data.SqlClient"/>
	</connectionStrings>
или RSS канал: Что новенького на smarly.net