Страницы

Поиск по вопросам

среда, 22 мая 2019 г.

Несколько вопросов по ASP.MVC и AJAX

Я только разбираюсь в ASP.MVC и может быть задаю глупые вопросы. В данном случае вопросы будут не "как сделать", а "почему так происходит". Делаю проект, суть которого заключается в том, что он обходит сайт, собирает ссылки на его страницы и измеряет время отклика. Потом, собранную информацию выводит в табличном виде (пока). Проект состоит из двух страниц. На первой - в соответствующем инпуте водится поле и по нажатию кнопки идет переход на другой контроллер (ToolController), который производит замеры и выводит результаты.
Код метода первого контроллера (HomeController):
public ActionResult Submit(string Url) { if (CheckUrl(Url)) { ViewBag.Error = ""; return RedirectToAction("Index", "Tool", new { Url }); } else { ViewBag.Error = "Некорректный адрес!"; return RedirectToAction("Index"); }
}
Валидацию пока можно не смотреть, это буду отдельно разбираться.
Представление (фрагмент):
@using (Html.BeginForm("Submit", "Home", FormMethod.Post)) {

@Html.Label("Введите адрес сайта в поле ввода и нажмите кнопку")
@Html.TextBox("Url") @ViewBag.Error
}
Во ToolController есть поле private поле класса VMManager, методы которого реализуют бизнес-логику. В классе VMManager есть поле вью-модели (VM), потому что все дальнейшие действия будут крутиться вокруг один раз построенной VM (сохранение в БД - пока не реализовано). Представление выводит таблицу, состоящую из ссылок на страницы сайта (Ajax.ActionLink), по нажатию на которые должно подгружаться partialView с графическим представлением информации. До графического представления мне пока далеко, пока разобраться бы что в табличном происходит.
Фрагмент контроллера (ToolController):
private static VMManager manager = new VMManager();
public ToolController() { // manager = new VMManager(); } // GET: Tool public ActionResult Index(string url) { // manager = new VMManager(); manager.VM = (SiteVM)manager.GetVM(url);
return View(manager.VM); }
public ActionResult ShowPageResultInChart(string pattern) { if (pattern == "test") return null; Thread.Sleep(1000); return PartialView("ShowPageResultInChart"); }
Фрагмент представления:
@Html.Action("ShowPageResultInChart", new { pattern ="test" })


@foreach (var item in Model.PageResults) { @Ajax.ActionLink(item.PageAddress, "ShowPageResultInChart", new {pattern= item.PageAddress }, new AjaxOptions { UpdateTargetId = "ChartData", LoadingElementId = "LoadingIndicator" } )

@item.MinTime @item.AverageTime @item.MaxTime }
В частичном представлении пока смотреть нечего: строчка "Сработал Ajax" Теперь вопросы:
Если верить отладчику, то при первичной загрузке основной страницы запускается метод ShowPageResultInChart. Хотя он предполагался к запуску только при нажатии на Ajax.ActionLink. Почему, что я сделал не так? От этой беды я избавился условием в методе ShowPageResultInChart, но почему он срабатывает? Я правильно понимаю, что это противоречит смыслу Ajax? Разместить его ниже таблицы я не могу по условиям задания. Причем у меня сложилось впечатление, что запускается он как минимум 2 раза, но может я ошибаюсь. Судя по всему, у меня запускается несколько экземпляров второго контроллера. Это я понял по тому, что VM в процессе обнуляется и при нажатии на Ajax.ActionLink на входе метода ShowPageResultInChart VM = null. Такое впечатление, что первый экземпляр создается при выводе таблицы, второй - при нажатии на Ajax.ActionLink. От этой беды я избавился сделав поле менеджера статическим, но почему так происходит?


Ответ

1) ShowPageResultInChart вы вызываете не только с помощью @Ajax.ActionLink, а также с помощью @Html.Action, отсюда он и выполняется при загрузке страницы.
@Html.Action("ShowPageResultInChart", new { pattern ="test" })
2) При каждом запросе создается отдельный экземпляр класса Controller через ControllerFactory
Обратите внимание, что Html.Action Html Helper создаст другой экземпляр контроллера.
В общем, ControllerActivator.Create вызывается (для каждого запроса), чтобы создать контроллер (который создает новый контроллера или через DependencyResolver или через Activator, если не Resolver не был установлен):
public IController Create(RequestContext requestContext, Type controllerType) { try { return (IController) (_resolverThunk().GetService(controllerType) ? ? Activator.CreateInstance(controllerType)); }

Комментариев нет:

Отправить комментарий