我正在使用自定义角色提供程序,过度简化使用.net 4 MVC项目上的EF从数据库中获取人员对象,并根据围绕该(以及其他查询)的一些规则分配用户角色。
数据会定期更改,但更改是通过系统中其他位置的代码进行更改,而不是角色提供程序。角色提供者是一种方式,只需获取用户所在的角色。
当我更改数据库值时,角色管理器在重新编译之前不会接受角色更改(例如,通过在Web配置中添加空格),否则应用程序将重新启动。
我确保角色不会通过设置cacheRolesInCookie=false
来缓存在cookie中,这是大多数帮助似乎指出的,并假设在角色管理器中内置了会话缓存。
我修改了EF查询,该查询返回person对象以包含时间戳作为查询的一部分。我可以通过分析器看到实际上正在调用查询,并且时间戳每次都会更改,但我的调试会话显示来自“person”项的先前状态的陈旧数据。站点的其他部分显示Person表中的数据,这些数据显示最新状态。
我真的不明白调试器应该如何处理缓存数据。如果它是一个缓存问题,我不明白为什么EF查询会激活,但是人员数据肯定是按照第一次运行显示状态,而不是根据表行的当前状态。
我觉得我错过了一些明显的东西。角色管理器是否在会话中缓存数据?
答案 0 :(得分:3)
答案实际上取决于应用程序的体系结构。我最近遇到了这个问题,并且还指责了角色管理器缓存。事实证明,这是我的数据访问层中的实体上下文的管理。我正在管理我的实体上下文并按通常建议的方式存储每个请求的上下文。但问题是上下文由于不相关的缺陷而被设置两次,因此角色提供程序的上下文总是与应用程序的其余部分不同,并且只设置一次(因为角色提供程序在Application Start上实例化,而不是每个请求)。
我建议您查看如何存储数据上下文和跟踪,以查看与Role Manager相对于应用程序其余部分的存储方式。确保您确实只使用one context per request。
答案 1 :(得分:1)
我有一个答案“我可以清除此缓存吗?”
是的,您可以清除角色管理器缓存。
(注意:此方法与删除角色缓存cookie不同,并允许您在请求期间清除缓存。)
在第一次调用角色提供程序获取角色后,角色管理器将在HttpContext.Current.User中为当前用户缓存角色。
该缓存将在整个请求中的后续角色检查中使用,并且不会调用您的自定义角色提供程序。
但是,您可以强制角色管理器再次调用您的角色提供程序(并有效地从数据源重新获取角色),方法是将当前用户强制转换为RolePrincipal,然后调用SetDirty()
例如:
RolePrincipal currentUser = HttpContext.Current.User as RolePrincipal;
currentUser.SetDirty();