I'm wanting to cache the roles a user is in for each request that comes in. There are several places throughout any given page where where we have something like:
<% if(Roles.IsUserInRole("RoleName")) {%>
<!-- Conditional Rendering -->
<% } else if(Roles.IsUserInRole("AnotherRole") {%>
<!-- You get the point -->
<% } %>
Since this is all stored in a sql database, each of these requests hit the database. I know there are ways to cache the roles in a cookie, but I don't want to do that. Anyway, What I was thinking was something like this.
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;
}
}
Anyone see any issues with this? I know that ever call to UserRoles()
will lookup the item in the context and maybe this isn't the most effecient thing to do. What I really want to know is if this will cache it on a per-request basis so there's no overlap with other users request.
That looks safe enough at a quick glance. HttpContext.Current.Items is a per-HTTP request cache. Another option to consider to further reduce database calls would be to use session state.
Consider a scenario where you have a page with a lot of ajax stuff going on. Each ajax request will invoke a database call to load security roles, since they are all separate HTTP requests.
It will cache it per request, since you are using the current HttpContext
.
If you were using a static member, it would be cached till the web application was recycled.
As such it looks fine - a fairly common pattern in fact (using a static member as an in-memory cache or the current HttpContext
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With