1

I am coding an ASP.NET MVC 3 application. The Navigation menu is created dynamically from DB based on permission set for user, using a child action. Users are allocated to Usergroups/Roles, but then they can also have some certain specific additional permissions. I am having a Hashset being returned by Authorization Services for all the privileges for current user. Most of users would have same privileges as the usergroup (no additional privileges). So, i want to cache the navigation menu.

Questions, 1. I need to use VaryByCustom option for OutputCache attribute? 2. How should i create unique keys for hashtables having same set of permissions (may be added to hashset in different order)?

EagerToLearn
  • 827
  • 2
  • 14
  • 24

1 Answers1

1

1. I need to use VaryByCustom option for OutputCache attribute?

I suppose that's the best version. See here on SO or in this blog.

2. How should i create unique keys for hashtables having same set of permissions (may be added to hashset in different order)?

To build the cache key, I have used something similar to this in the past (uses a GetHashCode implementation):

public class Permission
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public override int GetHashCode() { return this.Id.GetHashCode(); }
}

public static string BuildCacheKey(HashSet<Permission> permissions)
{
    var hashCode = GetHashCode(permissions);
    return string.Format(CultureInfo.InvariantCulture, "permission_{0}", hashCode);
}

private static int GetHashCode(IEnumerable<Permission> permissions)
{
    unchecked
    {
        var hash = 17;
        foreach (var permission in permissions.OrderBy(p => p.Id))
        {
            hash = hash * 23 + permission.GetHashCode();
        }

        return hash;
    }
}

This should work with several permissions IMHO. If you only have a few permission combinations and not too complicated permission names, you could also just concat the names.

public static string BuildCacheKey(HashSet<Permission> permissions)
{
    var builder = new StringBuilder("permission_");
    foreach (var permission in permissions.OrderBy(p => p.Name))
    {
        builder.Append(permission.Name);
    }

    return builder.ToString();
}
Community
  • 1
  • 1
hangy
  • 10,765
  • 6
  • 43
  • 63
  • Yes, i can sort/reorder. Hashset is still a set of privilege objects, how do i generate the cache key - Hashcode? – EagerToLearn Mar 27 '12 at 19:53
  • @EagerToLearn I think that strategy could depend on how many privileges a normal user has (in total). A few or a few hundred? – hangy Mar 27 '12 at 20:05