| Украина, Киев |
Управление состоянием страниц на клиенте
Сохранение данных в состоянии сеанса
Любой пользователь при первом обращении к приложению получает свой сеанс, который выражается в выделении некоторого объема памяти на стороне сервера для хранения данных любого типа. Доступ к этим совместным данным осуществляется любой страницей через присоединенный к ней объект-словарь Session. За счет этого можно сохранять информацию на одной странице, а получать к ней доступ с другой страницы.
При поступлении первого клиентского запроса на объект страницы ASP.NET генерирует идентификатор сеанса размером 42 байта. Этот идентификатор сеанса включается в отклик сервера и является уникальным в пределах приложения. Если ни одна из страниц приложения, к которым обращается пользователь, не записывает в объект Session данные, то броузер не возвращает его в запросе серверу. Вместо этого сервер при каждом запросе генерирует новый идентификатор сеанса и включает его в отклик. Стоит только странице записать какие-нибудь данные в объект Session, идентификатор сеанса сразу фиксируется и запоминается броузером. После этого начинается обратный процесс, теперь уже броузер с каждым запросом начинает посылать на сервер сохраненный идентификатор сеанса, даже если в дальнейшем мы полностью очистим объект Session.
Когда клиент (броузер) присылает идентификатор сеанса, сервер по нему автоматически извлекает из места хранения данные сеанса и заполняет ими объект Session созданной страницы. После чего данные сеанса становятся доступными в коде этой страницы.
Идентификатор сеанса может пересылаться серверу с запросом двумя способами:
- С помощью cookie-набора с зарезервированным именем ASP.NET_SessionId
- С помощью включения в URL для клиентов, не поддерживающих cookie-наборы (использование измененных URL - адресов)
Идентификатор сеанса можно получить как значение Response. Cookies["ASP.NET_SessionID"] - при формировании первого отклика, или Session. SessionID - всегда. Но конкретное его значение нас, как правило, не интересует, поскольку процесс распознавания выполняется автоматически.
Данные сеанса могут сохраняться ASP.NET в одном из трех мест на сервере, определяемых свойством Mode объекта Session:
- В оперативной памяти сервера внутри процесса - текущего домена приложения (режим InProc - установлен по умолчанию)
- В оперативной памяти сервера вне процесса в специальной службе Windows под названием ASP.NET State Service (режим StateServer )
- Вне процесса на жестком диске в базе данных SQL Server (режим SQLServer )
Состояние сеанса утрачивается в следующих случаях:
- Пользователь закрывает и вновь запускает броузер
- Пользователь получает доступ к приложению через другой броузер
- Из-за простоя сеанса больше определенного времени по причине отсутствия запросов от клиента (по умолчанию 20 минут)
- Программист завершает сеанс методом Session. Abandon()
- Если сеанс создается внутри текущего домена, то при переходе приложения в новый домен сеанс будет потерян
Сеанс является экземпляром класса System.Web.SessionState. HttpSessionState и может частично управляться из кода. В таблице приведены некоторые свойства и методы класса HttpSessionState
Начальное состояние сеанса устанавливается в конфигурационном файле web.config в секции <sessionState>. Настройки секции <sessionState> поддерживаются классом System.Web.Configuration.SessionStateSection через его свойства, но имена свойств в кофигурационном файле начинаются с символа нижнего регистра. Вот некоторые наиболее важные из них
При включенном режиме cookieless="true" броузер автоматически встраивает идентификатор сеанса в URL всех относительных ссылок. Это же справедливо и при автоматической переадресации на новую страницу методом Response.Redirect(" Относительный_адрес") с полным циклом. Для того, чтобы указать системе, что идентификатор сеанса должен передаваться секретным протоколом, нужно установить Response.Cookies["ASP.NET_SessionID"].Secure = true;
Приведем пример использования сеанса.
Упражнение 10. Использование механизма сессий
-
Отредактируйте
файл web.config приложения как показано ниже
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<compilation debug="true" />
<sessionState cookieless="true" regenerateExpiredSessionId="true" />
</system.web>
</configuration>
Листинг
35.22.
Файл web.config с включенным режимом Cookieless
-
Добавьте
страницу с именем SessionCookieless.aspx с
совмещенным кодом, которую заполните так
<%@ Page Language="C#" EnableViewState="false" %>
<script runat="server">
int clicks = 1;
const int maxCol=2;
HtmlTable table;
protected void Page_Load(object sender, EventArgs e)
{
string[] headers = {
// Имена свойств секции sessionState
"Cookieless",
"Mode",
"Timeout",
"RegenerateExpiredSessionId",
"CookieName",
// Дополнительная информация
"SessionID",
"numRequest",
"currentTime"
};
// Создаем объекты пользовательского интерфейса
// Текстовая метка заголовка
Label label = new Label();
form1.Controls.Add(label);
label.Text = "<h2>Использование сеансов Session</h2>";
if (!IsPostBack)
{
// Получаем всю информацию о параметрах конфигурации
System.Configuration.Configuration config;
config =
System.Web.Configuration.WebConfigurationManager.
OpenWebConfiguration(this.Request.ApplicationPath);
// Объявляем ссылку на объект SessionStateSection
System.Web.Configuration.SessionStateSection sessionState;
// Поиск элемента <sessionState> в элементе <system.web>
sessionState = (System.Web.Configuration.SessionStateSection)
config.GetSection(@"system.web/sessionState");
//sessionState.Timeout = TimeSpan.FromMinutes(1);
// Формируем таблицу и сохраняем ее в сеансе
table = new HtmlTable();
table.Border = 1;
for (int i = 0; i < headers.Length; i++)
{
// Создаем строку
HtmlTableRow row = new HtmlTableRow();
table.Rows.Add(row);
// Создаем ячейки в строке
for (int j = 0; j < maxCol; j++)
{
HtmlTableCell col = new HtmlTableCell();
row.Cells.Add(col);
if (j == 0)// Левый столбец
{
col.InnerHtml = headers[i] + ": ";
col.Align = "right";
col.BgColor = "Yellow";// Цвет фона
}
else // Правый столбец
{
// Применяем методику отражения типов
System.Type type = typeof(System.Web.Configuration.
SessionStateSection);
// Извлекаем публичное свойство по его имени
System.Reflection.PropertyInfo property =
type.GetProperty(headers[i]);
if (property != null)
{
col.InnerHtml = " ";
// Извлекаем значение свойства из экземпляра класса
col.InnerHtml += property.GetGetMethod().
Invoke(sessionState, null).ToString();
}
else
{
// Маркируем ячейку, чтобы потом найти
col.ID = headers[i];
}
col.BgColor = "#CCFFFF";// Цвет фона
}
}
}
// Сохраняем информацию в сеансе при первом запросе
this.Session.Add("table", table);
this.Session["clicks"] = clicks;
}
else
{
// Извлекаем информацию из сеанса при каждой обратной отсылке
table = (HtmlTable)this.Session["table"];
clicks = (int)this.Session["clicks"];
// Сохраняем новое значение
this.Session["clicks"] = ++clicks;
}
// Добавляем таблицу на форму
form1.Controls.Add(table);
// Корректируем таблицу
((HtmlTableCell)Page.FindControl("SessionID")).InnerHtml =
" " + this.Session.SessionID;
((HtmlTableCell)Page.FindControl("numRequest")).InnerHtml =
" " + clicks.ToString();
((HtmlTableCell)Page.FindControl("currentTime")).InnerHtml =
" " + DateTime.Now.ToLocalTime();
// Новая строка HTML
HtmlGenericControl br = new HtmlGenericControl();
br.InnerHtml = "<br />";
form1.Controls.Add(br);
// Кнопка Submit
Button submit = new Button();
form1.Controls.Add(submit);
submit.Text = "Отправить";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server" style="text-align: center;">
</form>
</body>
</html>
Листинг
35.23.
Код страницы SessionCookieless.aspx
-
Назначьте
страницу SessionCookieless.aspx стартовой
и выполните ее
Клиентский результат будет таким
Обратите внимание, что идентификатор сеанса встроен в URL при значении параметра Cookieless = "UseUri". Отметьте также, что интерфейсная часть страницы пустая - все создается динамически. Часть выводимой в таблицу информации мы добыли из объекта класса SessionStateSection, который создается по настройкам конфигурационного файла. Для более лаконичного кода мы применили методику отражения типов, позволившую опосредованно вызывать свойства объекта. В сессиях можно сохранять объекты любого типа, а не только строки. Но при извлечении их нужно явно приводить к соответствующему типу.
