Reputation: 9003
I know I can setup OutputCacheProfiles at web.config file.
I like to know how to apply different cache profile to different user role on page (controller) level?
Upvotes: 3
Views: 2135
Reputation: 1142
You can decorate a controller with the OutputCache attribute which allows arguments to be passed as parameters. For example;
[OutputCache(Duration = 3600, VaryByParam = "None")]
There is no reason why you couldn't extend the attribute to take a further argument "RoleName" and perform a "Roles.IsUserInRole(RoleName)" and load different settings based upon each role.
EDIT
After comments from the author, I have reviewed my solution.
Firstly, you can define you cache profiles within the Web.config;
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<clear />
<add name="Default" duration="60" />
<add name="Admin" duration="10" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
I have extended the OutputCacheAttribute to account for authorisation of a user, and if the user authenticates, it loads that CacheProfile;
public class AuthorisedOutputCache : OutputCacheAttribute
{
public string RoleName { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Default Profile.
CacheProfile = "Default";
if (HttpContext.Current.Request.IsAuthenticated)
{
if (Roles.IsUserInRole(RoleName))
{
CacheProfile = RoleName;
}
}
base.OnActionExecuting(filterContext);
}
}
Here is the Index.cshtml file for completeness;
@model DateTime
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
The time is @Model.TimeOfDay.ToString()
</p>
Note: You will have to make sure to define a cacheprofile for each of your roles, aswell as a default for when no role is found.
EDIT
The author wished to know how to set the cache profile within the controller, I have posted a viable solution, but I don't like it because of the use of HttpContext.Items - so if anyone can suggest alternatives?
Firstly, you must change the OnActionExecuting to OnActionExecuted;
public class AuthorisedOutputCache : OutputCacheAttribute
{
public string RoleName { get; set; }
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Do you wish to force the profile?
if (HttpContext.Current.Items["Cache.Force"] != null)
{
// Force the profile and remove the flag.
CacheProfile = HttpContext.Current.Items["Cache.Force"].ToString();
HttpContext.Current.Items.Remove("Cache.Force");
}
else
{
// If the profile has not been set - use the role based authorisation -
// otherwise, carry on as normal.
if (string.IsNullOrEmpty(CacheProfile))
{
CacheProfile = "Default";
if (HttpContext.Current.Request.IsAuthenticated)
{
if (Roles.IsUserInRole(RoleName))
{
CacheProfile = "Admin";
}
}
}
}
base.OnActionExecuted(filterContext);
}
}
The following line allows you to set the profile within the controller;
public ActionResult Index()
{
// Forces the cache profile to one of the name of "Mandatory".
HttpContext.Items["Cache.Force"] = "Mandatory";
return View(IndexViewName, DateTime.Now);
}
Let me know if I can be of further assistance,
Matt
Upvotes: 6