1

これは以前は機能していましたが、最近、ASP.NETがCookieにユーザーロールをキャッシュしていないことを発見しました。フィドラートレースを実行しましたが、Cookieの値が空白で、有効期限が過去に設定されているようです。したがって、Cookieは後続の要求で送信されず、DBはラウンドトリップごとにヒットします。

これに関する投稿が見つからないようです。どんな助けでも素晴らしいでしょう。ありがとう!

web.config

<roleManager enabled="true" defaultProvider="MyRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" createPersistentCookie="false">
  <providers>
    <clear />
    <add name="MyRoleProvider" type="MyCompany.Core.Web.Providers.MyRoleProvider" connectionStringName="MainConnect" applicationName="MyApplication" />
  </providers>
</roleManager>

フィドラーレスポンス(ヘッダー)

HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXROLES=; expires=Tue, 12-Oct-1999 05:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Mon, 31 Dec 2012 01:14:19 GMT
Content-Length: 1381
4

3 に答える 3

1

This answerを見てください。プロバイダーの IsUserInRole メンバーのみがこの方法で結果をキャッシュすることを示しているようです。ユーザー ロールを確認すると、ASP .NET MVC は GetRolesForUser のみを使用しているようです。私は少し前にこの同じ制限にぶつかりました。簡単なキャッシュ メカニズムを提供するためにロール プロバイダーに追加したコードを次に示します。

 public class MyRoleProvider : RoleProvider
 {
    private readonly string userRoleCacheKeyFormat;

    public MyRoleProvider()
    {
        userRoleCacheKeyFormat = this.Name + "_{0}";
    }

    public override string[] GetRolesForUser(string username)
    {
        return GetUserRoles(username);
    }

    private string[] GetUserRoles(string username)
    {
        string[] roleNames = null;

        if (!TryGetCachedUserRoles(username, out roleNames))
        {
            //cache miss
            roleNames = GetUserRolesFromStore(username);
        }

        return roleNames;
    }

    private bool TryGetCachedUserRoles(string username, out string[] userRoles)
    {
        string cacheKey = string.Format(userRoleCacheKeyFormat, username);
        HttpContext httpContext = HttpContext.Current;
        if (httpContext != null)
        {
            userRoles = (string[])httpContext.Cache.Get(cacheKey);
        }
        else { userRoles = null; }

        return (userRoles != null);
    }

    private void CacheUserRoles(string username, string[] userRoles)
    {
        string cacheKey = string.Format(userRoleCacheKeyFormat, username);
        HttpContext httpContext = HttpContext.Current;
        if (httpContext != null)
        {
            httpContext.Cache.Insert(cacheKey, userRoles, null, DateTime.UtcNow.AddMinutes(15), Cache.NoSlidingExpiration);
        }
    }

    private string[] GetUserRolesFromStore(string username)
    {
        MyDbContext db = MvcApplication.IoC.Resolve<MyDbContext>();

        string[] roleNames = db.Users
            .Single(u => u.Username == username)
            .UserRoles
            .Select(r => r.Name)
            .ToArray();

        CacheUserRoles(username, roleNames);

        return roleNames;
    }
}
于 2014-04-24T04:36:44.920 に答える
0

おもう。そのセッションには役割がありません。

于 2013-01-02T21:36:40.180 に答える