Профили

118

Ранее вы ознакомились с широким диапазоном средств безопасности ASP.NET. Многие из этих средств связаны с идентификацией индивидуальных пользователей (аутентификацией) и последующим определением действий, которые им разрешено выполнять (авторизацией). Однако уникально идентифицировать и аутентифицировать пользователей важно еще и по другой причине, а именно - чтобы отслеживать специфическую для конкретного пользователя информацию.

В ASP.NET 1.x единственная практическая возможность сохранять специфичную для пользователя информацию состояла в создании собственных компонентов доступа к данным. Веб-страница может вызывать методы этого компонента доступа к данным, чтобы получать данные текущего пользователя и затем сохранять любые изменения в них. Этот подход по-прежнему имеет смысл во многих сценариях. Однако в ASP.NET 2.0 появилось другое средство, называемое профилями, которое в ASP.NET 4 осталось неизменным. Когда используются профили, ASP.NET автоматически управляет извлечением специфичных для пользователя данных, обращаясь за ними к источнику данных заднего плана (обычно - к базе данных).

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

Одним из наиболее существенных отличий между профилями и другими типами управления состоянием является то, что профили предназначены для постоянного хранения информации с использованием источников данных заднего плана, таких как база данных. Большинство других типов управления состоянием предназначено для поддержки информации для последовательности запросов, поступающих за относительно короткое время (вроде непостоянных cookie-наборов и состояния представления), или для передачи информации от одной страницы к другой (такой как межстраничная отправка и строки запросов). Если нужно хранить информацию более длительное время в базе данных, то профили предоставляют для этого удобную модель, которая управляет хранением и извлечением информации.

Прежде чем начать применять профили, необходимо тщательно оценить их возможности. Этому посвящается несколько последующих разделов.

Производительность профилей

Назначение средства профилей ASP.NET заключается в обеспечении прозрачного способа управления специфичной для пользователя информацией без необходимости писать специальный код доступа к данным с применением классов данных ADO.NET.

К сожалению, многие средства, которые выглядят удобными, страдают от недостаточной производительности или масштабируемости. Это, в частности, касается профилей, поскольку они предполагают доступ к данным, а обращение к базам данных может легко превратиться в узкое место любого распределенного приложения.

Итак, испытывают ли профили проблемы масштабируемости? На этот вопрос не существует простого ответа. Все зависит от того, какой объем данных нужно хранить и как часто к ним необходимо обращаться. Чтобы принять взвешенное решение, понадобится узнать немного больше о том, как работают профили.

Профили подключаются к жизненному циклу страницы двумя способами:

Таким образом, средство профилей может дважды обращаться к базе данных при каждом запросе (в сценарии чтения-записи) или же всего один раз (если данные профиля просто читаются). Средство профилей не интегрировано с кэшированием, поэтому каждый запрос к данным профиля требует соединения с базой данных. Чтение и сохранение профилей реализовано специальным модулем ProfileModule, который запускается при каждом запросе.

С точки зрения производительности профили лучше работают, когда удовлетворяются следующие условия:

  1. Есть относительно немного страниц, которые обращаются к данным профиля.

  2. Сохраняется небольшой объем данных.

Хуже они работают при таких условиях:

  1. Есть много страниц, которые нуждаются в использовании информации профиля.

  2. Сохраняются большие объемы данных. Особенно низкая эффективность будет, когда необходимо использовать лишь некоторые из запрошенных данных (поскольку модель профилей всегда извлекает блок данных профиля целиком).

Конечно, профили можно комбинировать с другими типами управления состоянием. Например, предположим, что веб-сайт включает мастер заказов, который проводит пользователя через несколько шагов. В начале этого процесса информацию профиля можно извлечь и сохранить в состоянии сеанса. В остальной части процесса можно использовать коллекцию Session. Предполагая, что применяется модель хранения состояния сеанса на уровне серверного процесса или вне его, этот подход более эффективен, поскольку избавляет от необходимости периодически повторно подключаться к базе данных.

Как система профилей хранит данные

Наиболее существенное ограничение, касающееся профилей, никак не связано с производительностью - речь идет об ограничении сериализации профилей. Поставщик профилей по умолчанию, входящий в состав ASP.NET, сериализует информацию профилей в блок данных, который сохраняется в одном поле записи базы данных. Например, если сериализуется информация об адресе, в результате получается нечто вроде такого:

Alex ErohinЛенинский проспект 68Москва119296Россия

Другое поле указывает, где начинается и заканчивается каждое значение, с использованием формата вроде следующего:

Name:S:0:11:Street:S:11:21:City:S:32:6:ZipCode:S:38:6:Country:S:44:6

Хотя такой подход обеспечивает достаточную гибкость, чтобы хранить данные почти любого типа, он существенно затрудняет их применение в других приложениях. Можно написать специальный код для разбора данных профиля, чтобы найти нужную информацию, но в зависимости от объема данных и их типов этот процесс может оказаться весьма утомительным. И даже если сделать это, все же останется ограничение в способах использования такой информации.

Например, предположим, что профиль применяется дня хранения адреса заказчика. Из-за специфического формата не получится генерировать списки заказчиков в таких приложениях, как Microsoft Word, или выполнять запросы, которые фильтруют или сортируют записи с использованием данных профиля. (Например, выполнить запрос для получения всех заказчиков, живущих в определенном городе, не получится.)

Эта проблема имеет два решения:

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

Второй вариант интересен тем, что позволяет странице продолжать пользоваться моделью профилей. Фактически можно создать приложение, использующее стандартную сериализацию профилей с помощью SqlProfileProvider, а позднее переключиться на применение специального поставщика. Для такого переключения изменять код не понадобится. Нужно просто модифицировать настройки профиля в файле web.config. По мере того как веб-сайты будут шире применять профили, привлекательность специальных поставщиков профилей возрастет.

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

Профили и аутентификация

Одно существенное отличие профилей от других типов управления состоянием состоит в том, что профили сохраняются в индивидуальных записях, каждая из которых уникально идентифицирована именем пользователя. Это значит, что профили требуют применения систем аутентификации определенного рода. Не важно, какой конкретно тип аутентификации используется (аутентификация Windows, с помощью форм или специальная) - единственное требование состоит в том, что аутентифицируемому пользователю должно быть назначено уникальное имя. Это имя пользователя применяется для нахождения соответствующей записи профиля в базе данных.

Сравнение профилей и специальных компонентов данных

Профили - естественный конкурент специальных компонентов данных, вроде тех, которые строили в статье «Компонент доступа к данным». Ясно, что компоненты данных обладают большей гибкостью. Они позволяют не только поддерживать специфичную для пользователя информацию, но также сохраняют информацию и другого рода, а также позволяют решать сложные бизнес-задачи.

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

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

Шифрование

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

Проверка достоверности

Вы не можете ограничить тип информации, которая помещается в профиль. Для предотвращения появления недопустимых данных необходимо использовать дополнительные инструменты (такие как элементы управления проверкой достоверности и специальные классы данных).

Кэширование

Если информация профиля используется на странице, она всегда извлекается из базы данных. Информацию из профиля нельзя хранить в памяти. Хотя можно скопировать информацию профиля в кэш, это сильно затруднит ее отслеживание.

Диагностика

При проектировании пользовательского компонента базы данных имеется возможность добавлять любой необходимый код протоколирования и отслеживания. Его можно использовать для диагностики неожиданных ошибок или мониторинга производительности веб-приложения. Однако чтобы применять эти средства с профилями, придется построить собственный поставщик профилей, который включает необходимый код протоколирования.

Теперь, когда известны все подробности профилей, можно приступать к их использованию.

Пройди тесты
Лучший чат для C# программистов