Сохраняются ли объекты в WebForms в памяти? - PullRequest
0 голосов
/ 30 апреля 2018

У меня большой опыт работы с c #, но я довольно плохо знаком с WebForms.

Я работаю над проектом, в котором много данных хранится во ViewState, и я не понимаю, почему.

Насколько я понимаю, объект, представляющий мою страницу (System.Web.UI.Page), является постоянным в течение всей жизни этой страницы. Может быть какая-то закулисная магия, когда идентификатор хранится в ViewState, но, реагируя на события на этой странице, могу ли я просто ссылаться на «это» и его свойства / методы?

Когда я буду явно хранить данные во ViewState, а не просто использовать свойства текущего объекта (в данном случае Page)?

- Jacob

1 Ответ

0 голосов
/ 30 апреля 2018

Насколько я понимаю, объект, представляющий мою страницу (System.Web.UI.Page), является постоянным в течение всей жизни этой страницы

Это правильно, однако время жизни страницы только для одного запроса, после того, как HTML-код доставлен клиенту, экземпляр Page уничтожается.

Рекомендую прочитать эту статью: https://msdn.microsoft.com/en-us/library/ms178472.aspx

Обратите внимание, что дизайн WebForms: абстракция web без состояния в псевдосохраняющую WinForms-подобную среду в значительной степени считается ошибкой, и поэтому ASP.NET MVC и ASP.NET Core имеют радикально другой дизайн (хотя Controller экземпляры можно сравнить с Page экземплярами, с похожей семантикой жизненного цикла, но значительно меньшими накладными расходами).

Может быть какая-то закулисная магия, когда идентификатор хранится во ViewState, но, реагируя на события на этой странице, могу ли я просто ссылаться на «это» и его свойства / методы?

Мне трудно это понять - но если вы считаете, что все члены экземпляра Page, включая настраиваемые свойства, использующие только поле поддержки, автоматически сохраняются между запросами (включая запросы "обратной передачи"), то нет, то есть не правда. Волшебное постоянство для полей не требуется, необходимо использовать свойство Page.ViewState в качестве резервного хранилища для этих свойств, и эти данные сохраняются только между специальными запросами POST "postback".

Позвольте мне попробовать собственное объяснение:

  1. Браузер делает запрос на GET /MyForm.aspx
  2. ASP.NET создает новый экземпляр MyForm : System.Web.UI.Page, создает все дочерние элементы управления, объявленные в файле .aspx, и вызывает события Init и Load на всех элементах управления, а затем Render для сгенерировать вывод HTML, затем Unload. Экземпляр MyForm для запроса затем собирается сборщиком мусора.

Если MyForm.aspx содержит <form runat="server"> и использует «обратную передачу», то когда пользователь делает что-то, что вызывает обратную передачу, тогда:

  1. Браузер отправляет запрос в POST /MyForm.aspx, где тело запроса представляет собой данные из элементов <input >. Согласно правилам HTML, только содержимое <input><select>, <textarea> и т. Д.) Отправляется в запросе POST, а не во всем DOM - это проблема для ASP. NET WebForms, потому что все эти Controls имеют много свойств и настроек (например, <asp:Label FontColor="">, которые не сохраняются через их собственные <input type="hidden" name="label123_FontColor">, кроме того, даже если это было много подробных данных для отправки обратно на сервер.

Таким образом, вместо этого ASP.NET инструктирует все экземпляры Control сериализовать все свои не <input> данные в словарь ViewState (который представляет состояние View (на языке MVP / MVC .aspx / HTML является представлением - следовательно, сохраняется его состояние отдельно от состояния запроса, по определению кратковременного).

В подклассе Control или Page необходимо использовать ViewState, а не вспомогательное поле:

public String SomeName {
    get { return this.ViewState["SomeName"] as String; }
    set { this.ViewState["SomeName"] = value; }
}

... а затем ViewState сериализуется, сжимается, подписывается и отображается на странице в <input name="__VIEWSTATE" type="hidden">).

Состояние причины заносится в __VIEWSTATE вместо простой регенерации данных всей страницы при каждом запросе страницы, потому что иногда генерация страницы первоначально может включать в себя тяжелую работу (например, запрос БД). Аргумент заключается в том, что если у вас есть страница со списком данных, и пользователь просто манипулирует этими данными, прежде чем сохранить их обратно в БД, вам не нужно перезагружать данные из БД и вместо этого сохранять эти данные уровня просмотра в __VIEWSTATE страницы, как будто это какой-то супер-cookie или что-то в этом роде.

...