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