I have an ASP.NET MVC application. I need to cache some pages however only for non-authenticated users.
I've tried to use VaryByCustom="user"
with the following GetVaryByCustomString
implementation:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "user")
{
if (context.User.Identity.IsAuthenticated)
{
return context.User.Identity.Name;
}
else
{
return "";
}
}
return base.GetVaryByCustomString(context, custom);
}
However this isn't exactly what I need because pages are still cached. Only difference is that now is cached for each user separately.
One possible solution is to return Guid.NewGuid()
each time when user is Authenticated, but it looks like a huge waste of resources to me.
So do you have any tips for me?
The output cache enables you to cache the content returned by a controller action. That way, the same content does not need to be generated each and every time the same controller action is invoked. Imagine, for example, that your ASP.NET MVC application displays a list of database records in a view named Index.
There is a property of the OutputCache attribute 'Location' with following possible values: Any (Default): Content is cached in three locations: the web server, any proxy servers, and the web browser. Client: Content is cached on the web browser. Server: Content is cached on the web server.
In ASP.NET MVC, there is an OutputCache filter attribute that you can apply and this is the same concept as output caching in web forms. The output cache enables you to cache the content returned by a controller action. Output caching basically allows you to store the output of a particular controller in the memory.
Caching is used to improve the performance in ASP.NET MVC. Caching is a technique which stores something in memory that is being used frequently to provide better performance. In ASP.NET MVC, OutputCache attribute is used for applying Caching.
So here is what I done:
public class NonAuthenticatedOnlyCacheAttribute : OutputCacheAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var httpContext = filterContext.HttpContext;
if (httpContext.User.Identity.IsAuthenticated)
{
// it's crucial not to cache Authenticated content
Location = OutputCacheLocation.None;
}
// this smells a little but it works
httpContext.Response.Cache.AddValidationCallback(IgnoreAuthenticated, null);
base.OnResultExecuting(filterContext);
}
// This method is called each time when cached page is going to be
// served and ensures that cache is ignored for authenticated users.
private void IgnoreAuthenticated(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
if (context.User.Identity.IsAuthenticated)
validationStatus = HttpValidationStatus.IgnoreThisRequest;
else
validationStatus = HttpValidationStatus.Valid;
}
}
Many thanks to Craig Stuntz who pointed me to correct direction and whose answer I unwittingly downvoted.
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