I think the best way is with filters, then I'd use a regex to check if the result has HTML:
Create a filter:
public class NoCacheForHTMLResult : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
Regex tagRegex = new Regex(@"<[^>]+>");
string response = filterContext.RequestContext.HttpContext.Response.Output.ToString();
bool hasHtml = tagRegex.IsMatch(response);
if (hasHtml)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
}
...and add in the Global Filters (inside your App_Start
):
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new NoCacheForHTMLResult());
}
}
I'm not a regex expert, I got this regex from this question, but it looks we need to improve this, by checking if there is at least an HTML tag, otherwise if the result was XML, it looks the regex would match (though you might want to set no cache for XML as well, it's up to you).
The code for disabling cache I got in this answer, you might have a different code.
Hope this helps you.