Кэширует ли диспетчер ролей данные для поставщика настраиваемых ролей, и могу ли я очистить этот кеш?

Я использую настраиваемый поставщик ролей, который для упрощения получает объект человека из базы данных с помощью EF в проекте .net 4 MVC и распределяет роли пользователей на основе некоторых правил вокруг этого (и других запросов).

Данные меняются регулярно, хотя изменения осуществляются через код в другом месте системы, а не через поставщика ролей. Поставщик ролей является односторонним и просто получает роли, в которых находится пользователь.

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

Я обеспечил, чтобы роли не кешировались в cookie, установив cacheRolesInCookie=false, на что, по-видимому, указывает большая часть справки, и предполагаю, что в диспетчер ролей встроен кеш сеанса.

Я изменил запрос EF, который возвращает объект человека, чтобы включить отметку времени как часть запроса. Я могу видеть через профилировщик, что запрос действительно вызывается, и метка времени меняется каждый раз, но мой сеанс отладки показывает устаревшие данные из предыдущего состояния для элемента «человек». Есть и другие части сайта, которые отображают данные из таблицы Person, которые показывают актуальное состояние.

Я действительно не понимаю, как отладчик должен вести себя с кешированными данными. Я не понимаю, почему запрос EF вообще срабатывает, если это проблема с кешем, но данные о человеке определенно показывают состояние в соответствии с первым запуском, а не в соответствии с текущим состоянием строки таблицы.

Я чувствую, что упускаю что-то очевидное. Кэширует ли диспетчер ролей данные в сеансе?


person Adrian    schedule 14.10.2011    source источник
comment
Хотя я не понял, как это кэшируется, похоже, установка ролей через поставщика ролей решит проблему, а вызов кода напрямую в другом месте - нет. Я подозреваю, что у поставщика ролей есть собственный контекст данных, который немного устарел. В любом случае, я решу эту проблему, обойдя поставщика ролей.   -  person Adrian    schedule 19.10.2011


Ответы (2)


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

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

person jkriddle    schedule 02.08.2012
comment
Спасибо за ответ. Я пошел другим путем, хотя то, что вы описываете, очень мне помогает. Я подозреваю, что использовал контекст в объекте диспетчера безопасности. Если это было создано поставщиком роли при запуске, я подозреваю, что устаревший контекст застрял в памяти. Это объясняет, почему провайдер роли знал только об изменениях, внесенных им самим. Я до сих пор не понимаю данных профилировщика, но, возможно, я мог бы решить проблему, переместив контекст в метод, а не в класс. - person Adrian; 06.08.2012

У меня есть ответ на вопрос "Могу ли я очистить этот кеш?"

Да, вы можете очистить кеш диспетчера ролей.

(примечание: этот метод отличается от удаления файла cookie кэша роли и позволяет очистить кеш во время запроса).

Диспетчер ролей кэширует роли для текущего пользователя в HttpContext.Current.User после первого вызова поставщика ролей для получения ролей.

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

Однако вы можете заставить диспетчер ролей снова вызвать вашего поставщика ролей (и эффективно повторно захватить роли из источника данных), приведя текущего пользователя к RolePrincipal и затем вызвав SetDirty ()

Например:

RolePrincipal currentUser = HttpContext.Current.User as RolePrincipal;
currentUser.SetDirty();

См. документацию MS о методе RolePrincipal.SetDirty

person davrob01    schedule 10.10.2017