Страницы

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

пятница, 6 марта 2020 г.

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

#ajax #aspnet_mvc


Я только разбираюсь в 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



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)); }

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

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