IsUserInRole 调用 GetRolesForUser?
当我实现 RoleProvider 类并调用 Roles.IsUserInRole(string username, string roleName) 时,代码执行首先转到方法“GetRolesForUser(string username)”。这是为什么呢?当我只是寻找该用户是否属于一个角色的单一值时,我不想迭代所有角色。这是 .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();
}
When I implement the RoleProvider class and call Roles.IsUserInRole(string username, string roleName), code execution first goes to the method 'GetRolesForUser(string username)'. Why is this? I don't want to iterate all roles when I am just looking for the single value of whether that user belongs in one role. Is this a limitation of .NET's role provider class or is there something I can do to control the execution of code a bit more?
Here's the calling code
if (Roles.IsUserInRole(CurrentUser.UserName, "Teacher")) {
And here's the implementation of IsUserInRole
public override bool IsUserInRole(string username, string roleName) { return true; }
But the code GetRolesForUser always gets implemented first:
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
用户可以
Roles.Provider.IsUserInRole
而不是Roles.IsUserInRole
can user
Roles.Provider.IsUserInRole
instead ofRoles.IsUserInRole
Microsoft 的角色提供程序解决方案有一个层,可以在 cookie 中缓存用户的角色,因此不需要调用提供程序的 GetRolesForUser 方法。我相信 cookie 缓存是 Roles 类的一部分,因此只要您从 RoleProvider 基类实现,它就应该兼容。值得一看的是 Reflector 中的代码,以了解 MS 如何实现自己的抽象类,以及静态帮助器类的作用(角色和成员身份)
尝试将 cacheRolesInCookie="true" 添加到配置文件中的 roleManager 元素中,并查看流量是否发生变化。
由于您使用的是自己的 RoleProvider 实现,因此您还可以重写 IsUserInRole 方法并提供自己的实现来检查用户是否属于某个角色。
更新: 此代码块在 Roles.IsUserInRole 方法内部调用:
else 块将调用自定义提供程序的 IsUserInRole 方法。
因此您的用户的角色尚未添加到主体对象中。如果您还没有完成这一步,那么好吧。如果没有,请确保您这样做。它将确保每次调用 Roles.IsUserInRole 或 User.IsInRole 时,这些函数都会使用用户角色的内存缓存(加载后),而不必每次都访问数据库。 (尽管基本角色提供程序和角色管理器类应该为您处理这个问题。)
您可以验证角色提供程序的配置文件设置吗?另外,您使用的 .net 版本是什么?您是手动管理登录过程还是使用 .net 登录控件?您是否实现了自定义 Roles 类?或者您正在使用 System.Web.Security.Roles?
There's a layer Microsoft's role provider solution that enables caching a user's roles in a cookie so it doesn't need to call the provider's GetRolesForUser method. I believe the cookie caching is part of the Roles class, so as long as you implement from the RoleProvider base class, it should be compatible. It's worth a look at the code in reflector to get an idea of how MS implements their own abstract classes, and what the static helper classes do (Roles and Membership)
Try adding cacheRolesInCookie="true" to the roleManager element in your config file, and see if the flow changes.
Since you're using your own implementation of a RoleProvider, you can also override the IsUserInRole method and provide your own implementation of checking if a user is in a role.
UPDATE: This block of code gets called inside the Roles.IsUserInRole method:
The else block is what will call your custom provider's IsUserInRole method.
So the roles for your user have not yet been added to the Principal object. If you just haven't gotten around to that step yet, OK. If not, make sure you do that. It will make sure that every time you call Roles.IsUserInRole, or User.IsInRole that those functions will use an in-memory cache of the roles for the user (once loaded) instead of having to go to the database every time. (Although the base role provider and Roles manager class should take care of this for you.)
Can you verify the config file settings for the role provider? Also, what version of .net are you using? Are you manually managing the login process or are you using the .net login control? Have you implemented a custom Roles class? Or are you using the System.Web.Security.Roles?