Главная страница   /   12.2. Отладка MVC приложений (ASP.NET MVC 4

ASP.NET MVC 4

ASP.NET MVC 4

Адам Фриман

12.2. Отладка MVC приложений

Вы можете провести отладку ASP.NET MVC приложения точно так же, как и отладку ASP.NET Web Forms приложения. Отладчик (дебаггер) Visual Studio представляет собой мощный и гибкий инструмент, с большим количеством функций и задач. Мы можем лишь поверхностно охватить данную тему в этой книге, но и в последующих разделах мы покажем вам, как настроить отладчик и выполнять различные виды отладки для вашего MVC проекта.

Создание проекта

Чтобы продемонстрировать использование отладчика, мы создали новый MVC проект при помощи шаблона Basic. Мы назвали наш проект DebuggingDemo и проверили возможность создавать проект модульного теста, как показано на рисунке 12-3.

Рисунок 12-3: Создание проекта DebuggingDemo

Создайте новый контроллер Home и задайте ему содержание в соответствии с листингом 12-1. Выражения в методах действия не делают ничего интересного, но мы будем использовать их, чтобы продемонстрировать различные функции отладки.

Листинг 12-1: Начальное содержание контроллера Home
using System.Web.Mvc;
namespace DebuggingDemo.Controllers
{
	public class HomeController : Controller
	{
		public ActionResult Index()
		{
			int firstVal = 10;
			int secondVal = 5;
			int result = firstVal / secondVal;
			ViewBag.Message = "Welcome to ASP.NET MVC!";
			return View(result);
		}
	}
}

Кликните правой кнопкой мыши по методу действия Index, выберите Add View из всплывающего меню и создайте новое представление. Установите класс Model на int и снимите галочку с опции Use a layout or master page, как показано на рисунке 12-4.

Рисунок 12-4: Создание представления

Нажмите кнопку Add и отредактируйте содержание представления, чтобы оно соответствовало листингу 12-2. Это очень простое представление, которое просто отображает значение модели представления и ViewBag свойство, которое мы определили в методе действия Index.

Листинг 12-2: Начальное содержание представления Index.cshtml
@model int
@{
	Layout = null;
}
<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="width=device-width" />
	<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
	<title>Index</title>
</head>
<body>
	<h2 class="message">@ViewData["Message"]</h2>
	<p>
		The calculation result value is: @Model
	</p>
</body>
</html>

Последний подготовительный шаг, который нам нужно сделать, заключается в том, чтобы добавить стиль в файл /Content/Site.css, как показано в листинге 12-3.

Листинг 12-3: Добавление стиля в файл /Content/Site.css
...
.message {
	font-size: 20pt;
	text-decoration: underline;
}
...

Запуск отладчика Visual Studio

Отладка MVC приложений управляется по-другому, нежели отладка других приложений Visual Studio. Visual Studio настраивает отладку по умолчанию, но вам полезно знать, как изменить конфигурацию.

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

Листинг 12-4: Атрибут debug в файле Web.config
...
<system.web>
	<httpRuntime targetFramework="4.5" />
	<compilation debug="true" targetFramework="4.5" />
	<pages>
		<namespaces>
			<add namespace="System.Web.Helpers" />
			<add namespace="System.Web.Mvc" />
			<add namespace="System.Web.Mvc.Ajax" />
			<add namespace="System.Web.Mvc.Html" />
			<add namespace="System.Web.Routing" />
			<add namespace="System.Web.WebPages" />
		</namespaces>
	</pages>
</system.web>
...

Часть компиляции MVC проекта приходится на тот момент, когда приложение запускается в IIS, и поэтому вы должны убедиться, что атрибут debug установлен на true во время процесса разработки. Это гарантирует, что отладчик сможет работать с файлами классов, которые создаются по требованию компиляции.

Внимание

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

Кроме работы с файлом Web.config мы должны убедиться, что Visual Studio включает информацию об отладке в файлы классов, которые она создает. Это не критично, но могут возникнуть проблемы, если различные настройки отладки не синхронизированы. Убедитесь, в панели Visual Studio выбрана конфигурация Debug, как показано на рисунке 12-5.

Рисунок 12-5: Выбор конфигурации Debug

Для отладки MVC приложения выберите команду Start Debugging из Visual Studio меню Debug или нажмите на зеленую стрелку на панели управления Visual Studio (вы можете увидеть ее на рисунке 12-4 рядом с названием браузера, который будет использоваться для отображения приложения, в данном случае – Internet Explorer).

Если при запуске отладчика атрибут debug в файле Web.config установлен на false, то Visual Studio отобразит диалоговое окно, показанное на рисунке 12-6. Выберите вариант, который позволяет Visual Studio редактировать файл Web.config, и нажмите кнопку ОК, и отладчик запустится.

Рисунок 12-6: Диалоговое окно, которое отображает Visual Studio, если в файле Web.config отключена отладка

Тогда ваше приложение запустится и отобразится в новом окне браузера, как показано на рисунке 12-7.

Рисунок 12-7: Запуск отладчика

Отладчик будет работать с приложением, но вы не заметите никакой разницы, пока отладчик не дойдет до точки остановки (мы объясняем, что это значит, в следующем разделе). Чтобы остановить отладчик, выберите Stop Debugging из Visual Studio меню Debug или закройте окно браузера.

Остановка отладчика Visual Studio

Приложение, запущенное с отладчиком, будет вести себя нормально, пока не произойдет остановка, и в этот момент выполнение приложения прекращается и управление передается отладчику. И теперь вы можете проверять и контролировать состояние приложения. Остановки происходят по двум основным причинам: при достижении точки остановы (брекпойнта) или когда возникает необработанное исключение. Вы увидите примеры того и другого в следующих разделах.

Совет

Вы можете вручную остановить отладчик в любое время, выбрав Break All из Visual Studio меню Debug, в то время как работает отладчик.

Использование брекпойнтов

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

Чтобы создать брекпойнт, щелкните правой кнопкой мыши по выражению из кода и выберите из контекстного меню Breakpoint –> Insert Breakpoint. Для примера поставьте брекпойнт напротив первого выражения метода действия Index контроллера Home, и вы увидите красную точку на поле текстового редактора, как показано на рисунке 12-8.

Рисунок 12-8: Использование брекпойнта для первого выражения метода действия Index

Чтобы увидеть результат от использования брекпойнта, запустите отладчик, выбрав Start Debugging из Visual Studio меню Debug. Приложение будет работать, пока не достигнет выражения, где был поставлен брекпойнт. Тогда отладчик остановится, приложение перестанет выполняться, и управление над ним перейдет к вам.

Visual Studio выделяет точки, когда было остановлено выполнение, желтым цветом, как показано на рисунке 12-9.

Рисунок 12-9: Нахождение брекпойнта

Примечание

Брекпойнт ловится только тогда, когда выполняется выражение, на которое он завязан. В нашем примере брекпойнт был достигнут сразу же, как только мы запустили приложение, потому что он находится внутри метода действия, который вызывается при запросе URL по умолчанию. Если вы поместите брекпойнт внутри другого метода действия, вы должны использовать браузер для запроса URL, связанного с этим методом.

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

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

Просмотр значений данных в редакторе кода

Наиболее распространенное использование брекпойнтов заключается в том, чтобы попытаться разыскать ошибки в коде. Перед тем как исправить ошибку, вы должны выяснить, что же происходит, и одна из самых полезных функций, которые предоставляет Visual Studio, заключается в возможности просматривать и контролировать значения переменных прямо в редакторе кода.

В качестве примера запустите приложение, используя дебаггер, и ждите, пока не будет достигнут брекпойнт, который мы добавили в предыдущем разделе. Когда отладчик остановится, переместите указатель мыши на выражение, которое определяет переменную result. Вы увидите небольшое всплывающее окошко, которое показывает текущее значение, что видно на рисунке 12-10. На самом деле окошко не совсем такое, на рисунке мы показали его увеличенную версию.

Рисунок 12-10: Отображение значения переменной в редакторе кода Visual Studio

Выполнение выражений в методе действия Index не достигло точки, где значения было присвоено переменной result, поэтому Visual Studio показывает нам значение по умолчанию, которое равно 0 типа int. Выберите пункт Step Over (или нажмите F10) в меню Visual Studio Debug, чтобы перейти к выполнению выражения, которое определяет свойство ViewBag.Message, и снова наведите курсор на переменную result. Мы выполнили выражение, которое присваивает значение переменной result, и вы можете увидеть результат на рисунке 12-11.

Рисунок 12-11: Переменной присвоено значение

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

Вы видите, что справа от значения в окошке есть значок. Если вы нажмете на этот значок, всплывающее окошко покажет, когда значение переменной изменится: это позволяет контролировать одну или несколько переменных и видеть, когда они меняются и каковы их новые значения.

Просмотр состояния приложения в окне отладчика

Visual Studio предоставляет несколько различных окон, которые можно использовать, чтобы получить информацию о вашем приложении, в то время как исполнение было приостановлено после брекпойнта. Полный список доступных окон отображается в Debug меню Windows, но двумя из наиболее полезных являются окна Locals и Call Stack. Окно Locals автоматически отображает значения всех переменных в текущей области, как показано на рисунке 12-12. Это дает вам возможность быстро просмотреть все переменные, которые вам интересны.

Рисунок 12-12: Окно Locals

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

Набор переменных, показанных в окне Locals, меняется, когда вы перемещаетесь по приложению, но если вы хотите глобально отслеживать переменную, то щелкните правой кнопкой мыши по одному из элементов, показанных в окне Locals, и выберите опцию Add Watch. Элементы в окне Watch не будут меняться, когда вы выполняете выражения в приложении.

В окне Call Stack показана последовательность вызовов, которые привели к выполнению определенного оператора. Это может быть очень полезно, если вы пытаетесь понять странное поведение приложения, потому что вы можете просмотреть стек вызовов и определить обстоятельства, которые привели к брекпойнту. (Мы не показал вам окно Call Stack на рисунке, потому что наше приложение довольно простое и ему не хватает глубины стека, чтобы предоставить полезную информацию. Но мы рекомендуем вам изучить это и другие окна Visual Studio, чтобы понять, какую информацию способен предоставить отладчик).

Совет

Вы можете добавлять брекпойнты в представления. Это может быть очень полезно, например, для проверки значений свойств модели представления. Вы добавляете брекпойнт в представление так же, как мы только что делали: щелкните правой кнопкой мыши по нужному выражению Razor и выберите Breakpoint -> Insert Breakpoint.

Остановка на исключении

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

Примечание

Только необработанные исключения вызывают остановку отладчика. Исключение становится обработанным, если вы ловите и обрабатываете его в блоке try...catch. Обрабатываемые исключения являются полезным инструментом программирования. Они используются, чтобы представить сценарий, при котором метод не в состоянии выполнить свою задачу и должен сказать об этом. Необработанные исключения плохие, потому что они представляют неожиданные условия, которые мы не смогли предугадать (и потому что они приводят пользователя на страницу с ошибкой).

Чтобы показать остановку на исключении, мы добавили небольшое изменение в метод действия Index, как показано в листинге 12-5.

Листинг 12-5: Добавление выражения, которое вызовет исключение
using System.Web.Mvc;
namespace DebuggingDemo.Controllers
{
	public class HomeController : Controller
	{
		public ActionResult Index()
		{
			int firstVal = 10;
			int secondVal = 0;
			int result = firstVal / secondVal;
			ViewBag.Message = "Welcome to ASP.NET MVC!";
			return View(result);
		}
	}
}

Мы изменили значение переменной secondVal на 0, что приведет к возникновению исключения в выражении, которое делит firstVal на secondVal.

Примечание

Мы также удалили точку останова из метода действия Index, щелкнув правой кнопкой мыши по значку брекпойнта на поле и выбрав Delete Breakpoint из всплывающего меню.

При запуске отладчика приложение будет работать, пока не появится исключение: и в этот момент возникнет всплывающее окно, описывающее исключение, как показано на рисунке 12-13.

Рисунок 12-13: Всплывающее окно, описывающее исключение

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

Использование Edit and Continue

Интересная возможность отладки Visual Studio называется Edit and Continue. Когда отладчик остановится, вы можете отредактировать код, а затем продолжить отладку. Visual Studio перекомпилирует приложение и воссоздаст состояние приложения, каким оно было на момент, когда остановился отладчик.

Включить Edit and Continue

Нам нужно включить Edit and Continue в двух местах:

  • В разделе Edit and Continue меню Debugging (выберите Options из меню Tools Visual Studio); убедитесь, что на Enable Edit and Continue поставлена галочка, как показано на рисунке 12-14.
Рисунок 12-14: Включение Edit and Continue в диалоговом окне Options
  • В свойствах проекта (выберите DebuggingDemo Properties из Visual Studio меню Project); щелкните раздел Web и убедитесь, что на Enable Edit and Continue поставлена галочка, как показано на рисунке 12-15.
Рисунок 12-15: Включение Edit and Continue в свойствах проекта

Изменение проекта

Возможность Edit and Continue несколько придирчива. Есть несколько условий, при которых она не может работать. Одно из таких условий присутствует в методе действия Index класса HomeController: использование динамических объектов. Чтобы обойти это, мы закомментировали строку, которая использует ViewBag в классе HomeController.cs, как показано в листинге 12-6.

Листинг 12-6: Удаление вызова ViewBag из метода Index
using System.Web.Mvc;
namespace DebuggingDemo.Controllers
{
	public class HomeController : Controller
	{
		public ActionResult Index()
		{
			int firstVal = 10;
			int secondVal = 0;
			int result = firstVal / secondVal;
			// Это выражение закомментировано
			//ViewBag.Message = "Welcome to ASP.NET MVC!";
			return View(result);
		}
	}
}

Мы должны сделать соответствующее изменение в представлении Index.cshtml, как показано в листинге 12-7.

Листинг 12-7: Удаление вызова ViewBag из представления
@model int
@{
	Layout = null;
}
<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="width=device-width" />
	<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
	<title>Index</title>
</head>
<body>
	<!-- Этот элемент закомментирован -->
	<!--<h2 class="message">@ViewData["Message"]</h2>-->
	<p>
		The calculation result value is: @Model
	</p>
</body>
</html>

Редактирование и продолжение

Мы готовы к демонстрации возможности Edit and Continue. Выберите Start Debugging из Visual Studio меню Debug. Приложение запустится с отладчиком и будет работать до тех пор, пока не достигнет линии, где мы выполняем несложное вычисление в методе Index. Значение второго параметра равно нулю, что приводит к исключению. В этот момент отладчик останавливается, и появляется всплывающее окно с подсказкой (как показано на рисунке 12-13).

Нажмите ссылку Enable editing в окне с подсказкой. В редакторе кода наведите курсор мыши на переменную secondVal и нажмите на значение в появившемся всплывающем окне. Введите 5 в качестве нового значения, как показано на рисунке 12-16.

Рисунок 12-16: Изменение значения переменной

Теперь выберите Continue из Visual Studio меню Debug, чтобы возобновить выполнение приложения. Новое значение, которое вы присвоили переменной, используется для генерации значения переменной result, как показано на рисунке 12-17.

Рисунок 12-17: Результат исправления ошибки при помощи Edit and Continue

Найдите минутку, чтобы понять то, что произошло здесь. Мы запустили программу с ошибкой: это была попытка разделить значение на ноль. Отладчик обнаружил исключение и остановил выполнение программы. Мы отредактировали код, чтобы исправить ошибку, заменив значение переменной на 5. Затем мы сказали отладчику продолжить выполнение программы.

И в этот момент Visual Studio перекомпилировала наше приложение так, чтобы изменения были включены в процесс сборки, заново запустила выполнение программы, воссоздала состояние, которые привело к исключению, а затем продолжила работу, как обычно. В браузере отобразился результат, к которому привели наши изменения.

Без Edit and Continue нам нужно было бы остановить приложение, сделать изменения, скомпилировать приложение и перезапустить отладчик. Затем нам нужно было бы использовать браузер, чтобы повторить шаги, которые мы сделали до момента, когда остановился отладчик. Функция Edit and Continue является достаточно важной. Исправление сложных ошибок может потребовать повторения множества шагов по всему приложению, а возможность протестировать потенциальные исправления без необходимости повторять эти шаги снова и снова может сильно сэкономить время программиста.