ASP.NET中的Per-Request静态数据

时间:2011-02-09 20:45:55

标签: c# .net asp.net thread-safety httpcontext

我想要为每个请求缓存用户所处的角色。在任何给定页面中有几个地方我们有类似的地方:

<% if(Roles.IsUserInRole("RoleName")) {%>
    <!-- Conditional Rendering -->
<% } else if(Roles.IsUserInRole("AnotherRole") {%>
    <!-- You get the point -->
<% } %>

由于这都存储在sql数据库中,因此每个请求都会访问数据库。我知道有办法在cookie中缓存角色,但我不想这样做。无论如何,我在想的是这样的。

public static class SecurityUtils
    {
        public static string[] UserRoles()
        {
            var context = HttpContext.Current;

            if (context == null) return Enumerable.Empty<string>();

            string[] roles;

            roles = context.Items["UserRoles"] as string[];

            if (roles == null)
            {
                roles = Roles.GetRolesForUser();
                context.Items["UserRoles"] = roles;
            }

            return roles;
        }
    }

有人发现此问题吗?我知道,对UserRoles()的调用会在上下文中查找项目,也许这不是最有效的事情。我真正想知道的是,这是否会基于每个请求缓存它,因此与其他用户请求没有重叠。

2 个答案:

答案 0 :(得分:11)

快速浏览一下看起来很安全。 HttpContext.Current.Items是一个每HTTP请求缓存。考虑进一步减少数据库调用的另一个选择是使用会话状态。

考虑一个场景,你有一个包含很多ajax内容的页面。每个ajax请求都将调用数据库调用来加载安全角色,因为它们都是单独的HTTP请求。

答案 1 :(得分:3)

它会根据请求缓存它,因为您使用的是当前HttpContext

如果您使用静态成员,它将被缓存,直到Web应用程序被回收。

因此它看起来很好 - 实际上是一个相当常见的模式(使用静态成员作为内存缓存或当前HttpContext)。