C# ASP.NET中每个请求的静态数据

C# ASP.NET中每个请求的静态数据,c#,.net,asp.net,thread-safety,httpcontext,C#,.net,Asp.net,Thread Safety,Httpcontext,我想缓存用户在每个请求中的角色。在任何给定页面中,都有几个地方可以看到类似的内容: <% if(Roles.IsUserInRole("RoleName")) {%> <!-- Conditional Rendering --> <% } else if(Roles.IsUserInRole("AnotherRole") {%> <!-- You get the point --> <% } %> 由于这些请求都存

我想缓存用户在每个请求中的角色。在任何给定页面中,都有几个地方可以看到类似的内容:

<% 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;
        }
    }
公共静态类SecurityUtils
{
公共静态字符串[]UserRoles()
{
var context=HttpContext.Current;
if(context==null)返回Enumerable.Empty();
字符串[]角色;
roles=context.Items[“UserRoles”]作为字符串[];
如果(角色==null)
{
roles=roles.GetRolesForUser();
context.Items[“UserRoles”]=角色;
}
返回角色;
}
}

有人看到这有什么问题吗?我知道调用
UserRoles()
会在上下文中查找项目,也许这不是最有效的方法。我真正想知道的是,它是否会在每个请求的基础上缓存它,这样就不会与其他用户的请求重叠。

它会在每个请求中缓存它,因为您使用的是当前的
HttpContext

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


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

一看就足够安全。HttpContext.Current.Items是每个HTTP请求的缓存。另一个考虑进一步减少数据库调用的选项是使用会话状态。
考虑这样一个场景,您有一个包含大量ajax内容的页面。每个ajax请求都将调用一个数据库调用来加载安全角色,因为它们都是单独的HTTP请求

@bzlm-也许这些角色不是可序列化的?@Oded你是对的。也许问题中的代码示例中的
string[]
指的是彩虹和独角兽,而不是字母和数字的序列。@bzlm这不是一个像“你能找出这有什么问题吗?”这样的技巧性问题,我知道一些你不知道的东西。=)@bzlm上次我检查了彩虹和独角兽是否可以序列化。@Micah只是想知道,既然
Session
显然是存储角色列表的地方,除非您特别想要每请求缓存。@Oded:您能解释一下吗:这将被缓存,直到web应用程序回收。?我的理解是HttpContext。Items是每请求缓存,不是吗?即@Ladislav Mrnka-在.NET web应用程序重置自身之前,有一段默认时间。我的意思是,直到它被重置,手动或自动。啊,我知道你的回答是什么。他的静态成员是一个方法,而不是一个字段。@Oded:但它仍然没有解释为什么HttpContext实例和相关项不应该提供每个请求的缓存,以及为什么它们应该一直存在到web应用程序回收为止——至少这是我对您答案的理解。这是关于ajax请求等的一个重要观点。我可能会使用session,但只要确保在用户添加或更改角色时清除session即可。我将指出使用session减少数据库调用的一个可能很明显的警告——您可以将实际的session provider配置为数据库或外部服务器(如Redis、AWS DynamoDb),所以请注意环境是如何设置的。我知道这很旧,但我相信你的意思是
HttpContext
而不是
HttpContent
谢谢@Davy8我修正了答案中的错误