Эффективное использование ASP.NET WebForms 4.0: ViewState
ViewState является важным механизмом разработки приложений на ASP.NET. Этот механизм позволяет сохранять состояние представления веб-страницы для повторного использования на сервере. ViewState - это мощный функционал, но его неверное использование может ухудшить работу веб-приложений, увеличив размер страниц и объем данных передаваемых между сервером и клиентом.
Управление ViewState
Для более гибкого управления механизмом ViewState в ASP.NET 4.0 были добавлены дополнительные рычаги, позволяющие разработчикам эффективнее использовать сохранение состояния страниц.
Ранее существовал только один способ управления сохранением состояния страниц – свойство EnableViewState у класса страницы. Это свойство позволяло централизованно включать или выключать механизм сохранения состояния для каждой из страниц. Однако, наиболее общим сценарием при разработке веб-приложений является сценарий, когда вам требуется сохранить состояние определенных элементов на страницы, но не всей страницы сразу. В ASP.NET предыдущих версий выполнить это было довольно сложно, поскольку при выключении состояния для всей страницы, не было возможности включить его для определенных элементов.
Для устранения этого ограничения в ASP.NET 4.0 было добавлено новое свойство ViewStateMode, которое позволяет гораздо лучше управлять состоянием страниц. Свойство ViewStateMode может принимать три значения:
- Disabled – запрещает использование механизма сохранения состояния для элемента и по умолчанию запрещает сохранение для всех вложенных в него элементов;
- Enabled – позволяет использование механизма сохранения состояния для элемента и по умолчанию позволяет сохранение для всех вложенных в него элементов;
- Inherit – указывает на то, что управление механизмом сохранения состояния должно наследоваться от родительского элемента.
Важное отличие нового свойства ViewStateMode от EnableViewState состоит в том, что каждый вложенный элемент может переопределить значение ViewStateMode для управления собственным состоянием. Таким образом, вы можете запретить по умолчанию сохранение состояние для всей страницы и разрешить только для тех элементов, которым этот механизм действительно нужен.
На примере ниже для страницы значение ViewStateMode установлено в “Disabled”, что означает запрет на сохранение состояния по умолчанию для всех элементов страницы.
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" ViewStateMode="Disabled" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<p>
<asp:Label runat="server" ID="FirstLabel" ViewStateMode="Enabled"
Text="Первое сообщение (ViewStateMode = Enabled)."></asp:Label>
<asp:Label runat="server" ID="SecondLabel" ViewStateMode="Disabled"
Text="Первое сообщение (ViewStateMode = Disabled)."></asp:Label>
<asp:Button runat="server" Text="Отправить" />
</p>
</asp:Content>
Однако, для метки FirstLabel значение ViewStateMode установлено в "Enabled", что говорит о нашем желании использовать ViewState для этого элемента. Теперь у двух меток будет разное поведение при изменении их значения. На примере ниже мы изменяем значение меток при первой загрузки страницы.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
FirstLabel.Text = "Привет, мир!";
SecondLabel.Text = "Привет, мир!";
}
}
После этого, при первой загрузки страницы мы увидим на странице обновленные метки.
После нажатия на кнопку “Отправить”, в результате при обновлении страницы через механизм PostBack, одна из меток изменит свое состояние на состояние по умолчанию, а у другой состояние останется таким каким оно было сохранено.
Таким образом, с помощью нового механизма ViewStateMode мы смогли ограничить сохранение состояние только для тех элементов на странице, которым это действительно нужно.
Использование механизма ControlState
Существует способ использовать ViewState и при установленном значении EnableViewStatу = False для всей страницы, эта техника основывается на использовании механизма сохранения состояния ControlState. И если ViewState выключить можно, то ControlState — нет.
Рассмотрим пример:
[Serializable]
struct PageStateStruc
{
public FormState CurrentState;
public int? CurrentResume;
public int CurrentSection;
}
PageStateStruc PageState;
protected override void OnInit(EventArgs e)
{
Page.RegisterRequiresControlState(this);
base.OnInit(e);
}
protected override object SaveControlState()
{
return PageState;
}
protected override void LoadControlState(object savedState)
{
PageState = (PageStateStruc)savedState;
}
Здесь определяется некая структура данных PageStateStruc, экземпляр которой мы будем сохранять. Обратите внимание на атрибут Serializable, который для используемой структуры обязателен. Тут же определяется экземпляр структуры PageState.
Далее, в обработчике OnInit вызывается метод RegisterRequiresControlState, который регистрирует текущую страницу как элемент управления, ControlState которого следует сохранять. Вместо this можно указать любой пользовательский элемент управления. Рекомендуется осуществлять вызов RegisterRequiresControlState именно в OnInit.
Завершают картину два перегруженных метода SaveControlState и LoadControlState, которые, как это видно, просто осуществляют загрузку и выгрузку необходимых данных. Вызов этих методов asp.net берет на себя.
Это все, данные PageState между запросами к странице будут автоматически сохраняться. По сути, для сохранения данных между вызовами страницы нам необходимо только определить вид данных и описать, как эти данные необходимо сохранять/загружать. Остальное делает инфраструктура ASP.NET.
Использование механизма Trace для слежения за ViewState
При разработке сложных веб-страниц со множеством элементов управления часто возникает необходимость отследить поведение страницы и параметры использования ViewState. В ASP.NET существует простой способ профилирования страниц – Trace. Просто добавьте в определение страницы значение Trace = True:
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" ViewStateMode="Disabled"
Trace="true" %>
Теперь после загрузки страницы вы будете получать подробную информацию по всем элементам страницы, в том числе объем ViewState используемый элементами: