首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Asp.net网站非常缓慢,因为每个页面上都有角色签入

Asp.net网站非常缓慢,因为每个页面上都有角色签入
EN

Stack Overflow用户
提问于 2012-07-09 21:20:11
回答 5查看 3.4K关注 0票数 2

我在我的ASP.NET应用程序中有角色。我已经算出了问题(我想)。应用程序中每个页面的问题都使用角色和权限。因此,它在页面加载中使用以下函数

如果(Roles.IsUserInRole("Admin")) { //显示页面} else { // No }

我从这个问题Poor Performance with WindowsTokenRoleProvider中找到了解决问题的方法

以上问题使用WindowsTokenRoleProvider,,我使用的是SqlRoleProvider

由于上述问题,上述解决方案对我来说并不完全适用。

到目前为止,我已经做了一些成功的工作,我从SqlRoleProvider导出了一个类,并包含了这个函数,这个函数与上面的问题相同,但经过了修改。我更改了web.config,使它看起来像这样

代码语言:javascript
运行
复制
<roleManager enabled="true" cacheRolesInCookie="true" cookieName=".ASPR0L3S" cookieTimeout="117" cookieSlidingExpiration="true" cookieProtection="All" createPersistentCookie="false" defaultProvider="CustomSqlRoleProvider">
            <providers>
                <add name="CustomizedRoleProvider" type="CustomSqlRoleProvider" connectionStringName="PEGConn" applicationName="/CRM"/>
            </providers>
        </roleManager>

这是我的类中的函数,它确实会得到(只有当用户登录时才执行)

代码语言:javascript
运行
复制
public override string[] GetRolesForUser(string username)
    {
        // Will contain the list of roles that the user is a member of
        List<string> roles = null;

        // Create unique cache key for the user
        string key = String.Concat(username, ":", base.ApplicationName);

        // Get cache for current session
        Cache cache = HttpContext.Current.Cache;

        // Obtain cached roles for the user
        if (cache[key] != null)
        {
            roles = new List<string>(cache[key] as string[]);
        }

        // Was the list of roles for the user in the cache?



        if (roles == null)
        {
            string[] AllRoles = GetAllRoles();
            roles = new List<string>();

            // For each system role, determine if the user is a member of that role
            foreach (String role in AllRoles)
            {
                if (base.IsUserInRole(username, role))
                {
                    roles.Add(role);
                }
            }

            // Cache the roles for 1 hour
            cache.Insert(key, roles.ToArray(), null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
        }

        // Return list of roles for the user
        return roles.ToArray();
    }

问题是当Roles.IsUserInRole函数调用相同的旧函数时

System.Web.Security.Roles.IsUserInRole

函数。我甚至在我的新类中重载了这个函数,但是它从未被执行过。我基本上是缓存所有角色,以便在每个页面上刷新应用程序不会从一开始就搜索所有角色。

我需要从System.Web.Security.Roles.IsUserInRole派生另一个类吗?有人做过吗。

每一页大约需要4-8秒的新鲜,这是太长。代码在VS 2008,C# 3.5中

EN

回答 5

Stack Overflow用户

发布于 2012-07-09 22:04:26

我认为这可能也隐藏了应用程序设计中的一个根本问题。你应该遵守干燥原则。不要重复自己,也就是不要在每个页面上重复相同的查找/代码。我建议使用会话变量,以便您可以“缓存”这些昂贵的角色查找。下面是使用会话变量的快速指南:

http://msdn.microsoft.com/en-us/library/ms178581.aspx

旁白。我看你在用曲奇来存储你的角色。这听起来不太安全,因此我假设安全性不是这个练习的主要目标。

票数 1
EN

Stack Overflow用户

发布于 2012-07-10 04:10:23

如果Roles.IsUserInRole("Admin")需要时间,那么您可以(登录时)检查用户的角色,并保存会话对象的值。

代码语言:javascript
运行
复制
const string IS_ADMIN_KEY; //this can be on a base class of page / master page

Session[IS_ADMIN_KEY] = Roles.IsUserInRole("Admin"); // do this when logging in

//Add this to page load
bool isAdmin = Session[IS_ADMIN_KEY]; 
if(isAdmin)) 
{ 
   // display the page 
} else 
{ 
   // don't display the page 
}
票数 1
EN

Stack Overflow用户

发布于 2014-10-15 13:51:43

  1. 我建议您利用GetRolesForUser的基类实现,而不是重复调用IsUserInRole,后者将在每次调用时访问数据库。 公共覆盖string[] GetRolesForUser(字符串用户名){ //创建用户字符串键=String.Concat(用户名,":",base.ApplicationName)的唯一缓存键;string[]角色= HttpRuntime.Cachekey作为string[];if (角色!= null) {角色=base.GetRolesForUser(用户名);HttpRuntine.Cache.Insert(密钥,roles.ToArray(),.}}
  2. 我还会考虑使用滑动到期,它的值可以是可配置的,默认为30分钟左右-类似于默认的RoleManagerSection.CookieTimeout)。这可能是在你的1小时的绝对期限之外。
  3. 最后,您应该重写IsUserInRole以使用缓存。它可按以下方式执行: 公共覆盖bool IsUserInRole(字符串用户名,字符串roleName) { //不区分大小写的比较与RolePrincipal类的兼容性返回RolePrincipal StringComparer.OrdinalIgnoreCase);}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11403341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档