for my current project it's necessary to generate dynamic CSS...
So, i have a partial view which serves as a CSS deliverer... The controller code looks like this:
[OutputCache(CacheProfile = "DetailsCSS")]
public ActionResult DetailsCSS(string version, string id)
{
// Do something with the version and id here.... bla bla
Response.ContentType = "text/css";
return PartialView("_css");
}
The output cache profile looks like:
<add name="DetailsCSS" duration="360" varyByParam="*" location="Server" varyByContentEncoding="none" varyByHeader="none" />
The problem is: When i use the OutputCache line ([OutputCache(CacheProfile = "DetailsCSS")]), the response is of content type "text/html", instead of "text/css"... when i remove it, it works as expected...
So, for me it seems that the OutputCache doesn't save my "ContentType" setting here... is there any way around this?
Thanks
You could overwrite the ContentType with your own ActionFilter that executes after the cache has occurred.
public class CustomContentTypeAttribute : ActionFilterAttribute
{
public string ContentType { get; set; }
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.ContentType = ContentType;
}
}
And then call that attribute after the OutputCache.
[CustomContentType(ContentType = "text/css", Order = 2)]
[OutputCache(CacheProfile = "DetailsCSS")]
public ActionResult DetailsCSS(string version, string id)
{
// Do something with the version and id here.... bla bla
return PartialView("_css");
}
Or (and I haven't tried this) but override the "OutputCacheAttribute" class with a CSS specific implementation. Something like this...
public class CSSOutputCache : OutputCacheAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.ContentType = "text/css";
}
}
and this...
[CSSOutputCache(CacheProfile = "DetailsCSS")]
public ActionResult DetailsCSS(string version, string id)
{
// Do something with the version and id here.... bla bla
return PartialView("_css");
}
This could be a bug in ASP.NET MVC.
Internally they have a type called OutputCachedPage
that derives from Page
. When OnResultExecuting
is called on OutputCacheAttribute
they create an instance of this type and call ProcessRequest(HttpContext.Current)
, which eventually calls SetIntrinsics(HttpContext context, bool allowAsync)
that sets the ContentType like this:
HttpCapabilitiesBase browser = this._request.Browser;
this._response.ContentType = browser.PreferredRenderingMime;
Here's a fix:
public sealed class CacheAttribute : OutputCacheAttribute {
public override void OnResultExecuting(ResultExecutingContext filterContext) {
string contentType = null;
bool notChildAction = !filterContext.IsChildAction;
if (notChildAction)
contentType = filterContext.HttpContext.Response.ContentType;
base.OnResultExecuting(filterContext);
if (notChildAction)
filterContext.HttpContext.Response.ContentType = contentType;
}
}
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