以下是我編寫的使用適當緩存的自定義角色提供程序的詳細信息,並且在每次頁面加載時都沒有命中數據庫。
=============我的代碼隱藏文件===============
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
}
}
====== =======我的代碼隱藏文件結束===============
============= My 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分鐘後自動過期。你可以在你認爲合適的時候修改它。
乾杯。
這裏對我來說同樣的問題。我很想用HttpRuntime.Cache實現自己的緩存。 – Kwex
感謝您的提示Kwex - 現在我知道我並不孤單,這肯定是項目中其他地方沒有圖書館的問題。你能說你如何實施它嗎? – HeManNew
請在下面找到我的回覆。 – Kwex