【问题标题】:ASP.NET Universal Providers - Roleprovider does not cache roles in cookieASP.NET Universal Providers - Roleprovider 不在 cookie 中缓存角色
【发布时间】:2012-09-04 07:55:03
【问题描述】:

具有讽刺意味的是,我的角色提供者不再将角色缓存在 cookie 中。那是早些时候工作的。不幸的是,我现在才注意到,所以我不能说是什么导致了这个问题。但我认为这与更新到通用提供者的新版本 1.2(8 月 16 日发布)有关。

我的角色提供者配置如下:

 <roleManager enabled="true" cacheRolesInCookie="true" cookieName="X_Roles" 
cookiePath="/" cookieProtection="All" cookieRequireSSL="true" cookieSlidingExpiration="true" cookieTimeout="1440" 
createPersistentCookie="false" domain="" maxCachedResults="25" defaultProvider="XManager_RoleProvider">
<providers>
<clear/>
<add name="XManager_RoleProvider" type="ManagersX.XManager_RoleProvider, AssemblyX" 
connectionStringName="XEntities" applicationName="/" rolesTableName="Roles" roleMembershipsTableName="Users_Roles"/>
</providers>
</roleManager>

角色管理器一切正常(登录视图、带有站点地图修剪的菜单等),但它不再缓存角色。会员提供者、会话状态等也正常工作,并且它们的 cookie 设置正确。

静态角色类的所有属性均已正确设置,Httpcontext(IsSecureConnection 等)中的所有内容也正确。

角色 cookie 之前已设置,但现在不再设置。我希望任何人都可以帮助我解决我的问题。

提前致谢。

最好的问候,

赫曼新

更新: 请问没有人有同样的问题或提示吗?

【问题讨论】:

  • 对我来说同样的问题。我很想使用 HttpRuntime.Cache 实现我自己的缓存。
  • 感谢 Kwex 的提示 - 现在我知道我并不孤单,这肯定是项目中其他地方没有的库的问题。能说说你是怎么实现的吗?
  • 请在下面找到我的回复。
  • 我还经历过缓存突然停止工作,除了对 .NET Framework 的更新之外,我没有进行任何更改。我也必须自己实现缓存......但我认为这不应该是答案。答案应该是如何通过 web.config 为角色提供者使用假定的内置缓存。

标签: cookies roles membership roleprovider


【解决方案1】:

以下是我编写的自定义角色提供程序的详细信息,它使用适当的缓存并且不会在每次页面加载时访问数据库。

============= 我的代码隐藏文件===============

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.Security;

namespace MyProject.Providers
{
    public class CustomRoleProvider : RoleProvider
    {
        #region Properties

        private static readonly object LockObject = new object();
        private int _cacheTimeoutInMinutes = 0;

        #endregion

        #region Overrides of RoleProvider

        public override void Initialize(string name, NameValueCollection config)
        {
            // Set Properties
            ApplicationName = config["applicationName"];
            _cacheTimeoutInMinutes = Convert.ToInt32(config["cacheTimeoutInMinutes"]);

            // Call base method
            base.Initialize(name, config);
        }

        /// <summary>
        /// Gets a value indicating whether the specified user is in the specified role for the configured applicationName.
        /// </summary>
        /// <returns>
        /// true if the specified user is in the specified role for the configured applicationName; otherwise, false.
        /// </returns>
        /// <param name="username">The user name to search for.</param><param name="roleName">The role to search in.</param>
        public override bool IsUserInRole(string username, string roleName)
        {
            // Get Roles
            var userRoles = GetRolesForUser(username);

            // Return if exists
            return userRoles.Contains(roleName);
        }

        /// <summary>
        /// Gets a list of the roles that a specified user is in for the configured applicationName.
        /// </summary>
        /// <returns>
        /// A string array containing the names of all the roles that the specified user is in for the configured applicationName.
        /// </returns>
        /// <param name="username">The user to return a list of roles for.</param>
        public override string[] GetRolesForUser(string username)
        {
            // Return if User is not authenticated
            if (!HttpContext.Current.User.Identity.IsAuthenticated) return null;

            // Return if present in Cache
            var cacheKey = string.format("UserRoles_{0}", username);
            if (HttpRuntime.Cache[cacheKey] != null) return (string[]) HttpRuntime.Cache[cacheKey];

            // Vars
            var userRoles = new List<string>();
            var sqlParams = new List<SqlParameter>
                                {
                                    new SqlParameter("@ApplicationName", ApplicationName),
                                    new SqlParameter("@UserName", username)
                                };

            lock (LockObject)
            {
                // Run Stored Proc << Replace this block with your own Database Call Methods >>
                using (IDataReader dr =
                    BaseDatabase.ExecuteDataReader("aspnet_UsersInRoles_GetRolesForUser", sqlParams.ToArray(),
                                                   Constants.DatabaseConnectionName) as SqlDataReader)
                {
                    while (dr.Read())
                    {
                        userRoles.Add(dr["RoleName"].ToString());
                    }
                }
            }

            // Store in Cache and expire after set minutes
            HttpRuntime.Cache.Insert(cacheKey, userRoles.ToArray(), null,
                                     DateTime.Now.AddMinutes(_cacheTimeoutInMinutes), Cache.NoSlidingExpiration);

            // Return
            return userRoles.ToArray();
        }

        /// <summary>
        /// Gets or sets the name of the application to store and retrieve role information for.
        /// </summary>
        /// <returns>
        /// The name of the application to store and retrieve role information for.
        /// </returns>
        public override sealed string ApplicationName { get; set; }

        // I skipped the other methods as they do not apply to this scenario

        #endregion
    }
}

============= 我的代码隐藏文件结束===============

============= 我的 Web.Config 文件 =======================

<roleManager enabled="true" defaultProvider="CustomRoleManager">
  <providers>
    <clear />
    <add name="SqlRoleManager" type="System.Web.Security.SqlRoleProvider" connectionStringName="AspnetDbConnection" applicationName="MyApplication"/>
    <add name="CustomRoleManager" type="MyProject.Providers.CustomRoleProvider" connectionStringName="AspnetDbConnection" applicationName="MyApplication" cacheTimeoutInMinutes="30" />
  </providers>
</roleManager>

============= 我的 Web.Config 文件结束 ================

缓存设置为每 30 分钟后自动过期。您可以根据需要进行修改。

干杯。

【讨论】:

  • 非常感谢您的帮助;)!我会像你一样实现缓存。非常好。
【解决方案2】:

我遇到了同样的问题,但我找到了一篇似乎已解决该问题的 MS 知识库文章。我安装了补丁,cookie又出现了。

http://support.microsoft.com/kb/2750147

请参阅部分:ASP.Net 第 4 期。

希望对其他人有所帮助!

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 2012-03-02
    • 2012-08-18
    • 2010-12-27
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    相关资源
    最近更新 更多