Хранение и передача информации внутри приложения в ASP.NET

ASP.NET   11 марта 2012  Автор статьи:  

В данной статье мы поговорим про некоторые способы получения информации от пользователя и методы хранения ее на сервере. Информация которую передает нам пользователь может быть нужна нам только в момент запроса пользователя, а может использоваться спустя год. Она может хранится как на сервере, так и на компьютере пользователя. Доступ к ней может быть быстрый и медленный. Каждая конкретная задача определяет все эти параметры и задача программиста подобрать наилучший способ. Он может учитывать различные особенности хранения информации, такие как время ее жизни, безопасность, удобство ее получения и многие другие. Для более полного понимании ситуации с хранением и передачей информации в ASP.NET давайте рассморим следующую таблицу:

Состояние представления Строка запроса Cookie-наборы Состояние сеанса (Session) Состояние приложения (Application) Профили Кэширование
Допустимые типы данных Сериализуемые Строковые Строковые Сериализуемые Все Сериализуемые Все
Место хранения Скрытое поле URL-адрес Компьютер клиента Cервер Cервер. База данных Сервер.
Срок жизни Пока открыта страница Пока не изменен URL Срок жизни cookie Пока не истекло время сессии(обычно 20 минут). Равен сроку работы приложения Постоянный Зависит от настроек
Доступ Ограничивается страницей. Ограничивается страницей Все приложение Все приложение Все приложение Все приложение Все приложение.
Безопасность Слабая, но можно подвергнуть шифрованию Слабая Слабая Средняя Высокая Высокая Высокая
Производительность Высокая Высокая Высокая Средняя Средняя Низкая Средняя
Обычно применяется для: Для хранения параметров конкретной страницы. Для отправки информации о выборе конкретного продукта Для персонализации сайта Для более долгого хранения информации о выборе пользователя Для хранения глобальных данных Для хранения информации об учетной записи Для хранения данных, извлекаемых из базы данных.

Состояние просмотра(ViewState) — данный способ используется, если нужно хранить информацию в пределах одной страницы. Рассмотрим код для работы с ним:

ViewState["Size"]=1;// код кладет в коллекцию 1

Для извлечения нужно сначала проверить, а содержит ли коллекция ViewState параметр.

int size;
if(ViewState["Size"]!=null)
{
size = (int) ViewState["Size"];
}

Преимущества данного метода заключаются в том, что он не использует дополнительную память и не подвержен дополнительным ограничениям, единственные соображения по которым для решения данной задачи можно не использовать ViewState является большой объем информации, которую нужно сохранить, потому что при использовании ViewState хранит информацию внутри HTML кода страницы. Если вы собираетесь хранить информацию, которую нежелательна для просмотра пользователем, то используйте шифрование. Для повышения быстродействия иногда отключают ViewState у веб компонентов.

Строка запроса применяется чаще всего при выборке каких — то элементов на странице. Самый простой пример это поисковик, после ввода запроса вас перемещают на URL, которая содержит в себе после знака вопроса параметры, которые нужно передать, в случае с поисковиками это ваши слова. Например : /?s=ASP&x=13&y=4 На такую страницу вас переадрисует в случае, если вы введете на сайте cybern.ru в поисковик слово ASP, где серверу передается ключевое слово ASP через параметр s, и еще два дополнительных параметра x и y. Данный подход интересен тем, что не хранит информацию на сервере, тем самым повышая быстродействие системы в целом. Из критчиеских минусов данного способа передачи данных можно отметить невозможность использования некоторых символов, можно использовать только те, которые разрешены в URL адресах. При отправке запроса пользователь видит информацию которую отправляет, как и с приведенном выше примером и может в ручную изменить параметры, тем самым вызвав ошибку сервера, так как он не ожидает увидеть таких значений. Также через строку нельзя передавать объекты большой длины, во многих браузерах стоит ограничение на длину строки 2Кбайта. Для передачи несколкьи паркаметров в строку запроса нужно использовать амперсант (&) как и в примере /?s=ASP&x=13&y=4 В ASP.NET нет специальных инструментов для переадресации пользователя на страницу с специальными параметрами, поэтому вам придется самому создавать данные ссылки и отправлять туда пользователя.
Например:

Response.Redirect("Default.aspx?ID=1&keyWord=asp");

Если не указывать параметр ID или не задать его значение, то он будет null. Все значения параметров приводятся к строке, поэтому для извлечения параметров можно использовать следующий код:

string keyWord = Request.QueryString["keyWord"];

Как уже упоминалось выше строка состояния работает с очень ограниченным набором символов. В него входят буквы, цифры и специальные символы. У некоторых из них есть свое назначение, например плюс является альтернативой пробелу, & служит для склеивания параметров, а # для указания на якорь. Иногда, если вы неуверены, что используете только допустимые символы применяют URL кодирование. Для этого заменяют каждый символ его 16 — ричным кодом, указывая перед началом каждого символа %.

Response.Redirect("Default.aspx?ID=1&keyWord="Server.UrlEncode("asp");

Для раскодирования полседовательности символов можно использовать метод UrlDecode();
Cookie-наборы — это небольшие файлы, которые хранятся на компьютере пользователей. Интерес к ним возникает из — за простоты использования, так как пользователь даже не догадывается о их существовании. Ограничение данного способа хранения информации в ASP.NET является то, что он умеет работать только со строками, и также как строка запроса не может хранить большие объемы. Сейчас cookie распространены на большом количестве сайтов, потому что не существует другого способа хранить полезную информацию на клиенте. Но хранить секретную информацию в них не стоит, потому что они доступны для просмотра, также следует следить за тем, чтобы cookie были включены на компьютере пользователя, и то, что ваша запись не удалилась по истечению времени или в следствии нехватки памяти под cookie.

HttpCookie cookie = new HttpCookie("Name");//Создаем объект
cookie["keyword"] = "ASP";//кладем по ключу значение
Response.Cookies.Add(cookie);//добавляем cookie к ответу

Таким образом пользователь вместе со страничкой получит файл cookie, который будет содержать параметр keyword. Теперь при следующих обращениях пользователя мы сможем прочитать это значение и как — то на это среагировать. Понятно, что хранится наш файл cookie вечно на компьютере пользователя не будет, и что для каждого файла и параметра нужно задавать время жизни. В приведенном выше примере файл cookie удалится после закрытия браузера, если вы хотите, чтобы ваш файл cookie пожил подольше, то вам следует точно указать срок его жизни:

cookie.Expires = DateTime.Now.AddHours(1);//время жизни данного кука час

Теперь нужно научиться доставать информацию из cookie. Для этого мы по имени cookie обратимся к набору, проверим остался ли такой на компьютере пользователя и попробуем достать информацию.

HttpCookie cookie = Request.Cookies["Name"];//получаем cookie
string keyWord="";
if (cookie != null)// проверяем, что такой куки существует
{
keyWord = cookie["keyword"];
}

Для того, чтобы удалить cookie надо перезаписать его с прошедим временнем удаления.

cookie.Expires = DateTime.Now.AddHours(-1);

Состояние сеанса — это структура более высокого уровня, которая позволяет хранить не только строки, но и объекты ASP.NET. Данная технология работает следующим образом: для каждого клиента создается определенная коллекция в которой будет хранится необходимая ему информация. Т.е данные хранятся на сервере, а клиент должен просто передать некоторый идентификатор сессии. Если у клиента включены cookie, то скорей всего данный ключ будет передаваться через него, а если они выключены, то будет передаваться через строку запроса. Чтобы не загружать сервер лишними сессиями по умолчанию ставят ее длину равную 20 минутам, но вы можете изменить это время в зависимости от специфики разрабатываемого вами приложения. Рассмотрим простой пример работы с коллекцией Session:

//кладем в сессию
Session["keyWords"] = "ASP";
//достаем из сессии
string keyWord;
if(Session["keyWord"]!=null)
{
keyWord = Session["keyWord"].ToString();
}

В коллекцию можно класть любые сериализуемые типы.
Состояние приложения — это словарь, глобальный для всего приложения. Он имеет все плюсы и недостатки, которые есть у сессии, но его отличие в том, что он общий для всех пользователей. Таким образом в нем можно хранить данные, которые предоставляют ценность для всего домена(приложения): количество обащений, общие для всего сайта изменения и так далее. Рассмотрим простой пример работы с Application:

//положили в коллекцию
Application["keyWord"] = "ASP";
// взяли из коллекции
string keyWord="";
if (Application["keyWord"] != null)
{
keyWord = Application["keyWord"].ToString();
}

В завершении рассмотрения Application напишем код, который будет класть в переменную количество обращений к сайту.

protected void Page_Load(object sender, EventArgs e)
{
if (Application["requestCount"] != null)
{
int requestCount = (int)Application["requestCount"];
requestCount++;
Application["requestCount"] = requestCount;
}
else
{
Application["requestCount"] = 1;
}
}

Конечно объекты хранятся в Appplication, пока приложении будет запущенно, а не определенное время как в сессии, но из — за того, что Application глобально для всего приложения и к нему могут обратиться сразу одновременно много пользователей возникают проблемы сходные с многопоточным программированием(по факту это оно и есть). Поэтому наш счетчик может работать неправильно, если к нему допустим одновременно обратятся два клиента, потому что оба пользователя достанут из коллекции Application какое — то число, увеличат его на единицу и оба положат его назад, в результате все пользователи или запросы, которые произошли в один момент, буду считаться как один запрос, и наша переменная увеличит свое значение только ан единицу. Для обхода даннной проблемы есть функции Lock(); и Unlock():

protected void Page_Load(object sender, EventArgs e)
{
Application.Lock();
if (Application["requestCount"] != null)
{
int requestCount = (int)Application["requestCount"];
requestCount++;
Application["requestCount"] = requestCount;
}
else
{
Application["requestCount"] = 1;
}
Application.UnLock();
}

Таким образом мы не даем другому клиенту читать и писать в Application пока не завершим свои операции с ним.

  • Asd

    Класть параметры в сессию чтобы передавать их в рамках 1-2 страниц это жесткий говнокод!!!!!

  • Asd

    Класть параметры в сессию чтобы передавать их в рамках 1-2 страниц это жесткий говнокод!!!!!

  • Lordrp

    Так никто и не советует так делать) Сессия применяется для более долгого хранения информации о пользователе. Смотри таблицу.

  • Lordrp

    Так никто и не советует так делать) Сессия применяется для более долгого хранения информации о пользователе. Смотри таблицу.

Научиться программировать

  • на Delphi

  • на Java

  • на C++