当我实现RoleProvider类并调用Roles.IsUserInRole(字符串用户名,字符串roleName)时,代码执行首先转到方法'GetRolesForUser(字符串用户名)'。为什么是这样?当我只是在寻找该用户是否属于一个角色的单一值时,我不想重复所有角色。这是.NET角色提供程序类的限制,还是我可以做些其他事情来控制代码的执行?
这是调用代码
if (Roles.IsUserInRole(CurrentUser.UserName, "Teacher")) {
这是IsUserInRole的实现
public override bool IsUserInRole(string username, string roleName) { return true; }
但是始终总是首先实现代码GetRolesForUser:
public override string[] GetRolesForUser(string username) {
string[] roles = GetAllRoles();
List<string> userRoles = new List<string>();
foreach (string role in roles) {
if (IsUserInRole(username, role)) {
userRoles.Add(role);
}
}
return userRoles.ToArray();
}
最佳答案
Microsoft的角色提供程序解决方案有一层,它可以在cookie中缓存用户的角色,因此不需要调用提供程序的GetRolesForUser方法。我相信cookie缓存是Roles类的一部分,因此,只要从RoleProvider基类实现,它就应该兼容。值得一看的是反射器中的代码,以了解MS如何实现自己的抽象类以及静态帮助器类的功能(角色和成员资格)
尝试将cacheRolesInCookie =“true”添加到配置文件中的roleManager元素,并查看流程是否发生了变化。
由于您使用的是自己的RoleProvider实现,因此您还可以覆盖IsUserInRole方法,并提供自己的实现来检查用户是否在角色中。
更新:在Roles.IsUserInRole方法内部调用此代码块:
IPrincipal currentUser = GetCurrentUser();
if (((currentUser != null) && (currentUser is RolePrincipal)) && ((((RolePrincipal) currentUser).ProviderName == Provider.Name) && StringUtil.EqualsIgnoreCase(username, currentUser.Identity.Name)))
{
flag = currentUser.IsInRole(roleName);
}
else
{
flag = Provider.IsUserInRole(username, roleName);
}
else块将称为自定义提供程序的IsUserInRole方法。
因此,您的用户角色尚未添加到Principal对象。如果您还没有走到那一步,那就好。如果没有,请确保执行此操作。它将确保每次调用Roles.IsUserInRole或User.IsInRole时,这些函数将使用用户角色的内存缓存(一旦加载),而不必每次都访问数据库。 (尽管基本角色提供者和角色管理器类应为您解决这一问题。)
您可以验证角色提供程序的配置文件设置吗?另外,您正在使用什么版本的.net?您是手动管理登录过程还是使用.net登录控件?您是否实现了自定义的Roles类?还是您正在使用System.Web.Security.Roles?
关于c# - IsUserInRole调用GetRolesForUser吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4081618/