2009-11-18 75 views
15

为我目前的项目,它是必要的,以生成动态CSS ...ASP.NET MVC:输出缓存问题

所以,我有一个局部视图,作为一个CSS递送...控制器代码看起来像这样:

[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"); 
    } 

输出缓存配置文件看起来像:

<add name="DetailsCSS" duration="360" varyByParam="*" location="Server" varyByContentEncoding="none" varyByHeader="none" /> 

的问题是:当我使用的OutputCache线([的OutputCache(CacheProfile = “DetailsCSS”)]),响应内容键入“text/h tml“,而不是”文本/ css“...当我删除它,它按预期工作...

因此,对我来说似乎OutputCache不保存我的”ContentType“设置在这里.. 。 有没有办法解决?

感谢

回答

19

你可以使用您自己的ActionFilter覆盖ContentType,该ActionFilter在缓存发生后执行。

public class CustomContentTypeAttribute : ActionFilterAttribute 
{ 
    public string ContentType { get; set; } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     filterContext.HttpContext.Response.ContentType = ContentType; 
    } 
} 

然后在OutputCache之后调用该属性。或者(我没有尝试过这个),但是用一个CSS特定的实现覆盖“OutputCacheAttribute”类。事情是这样的......

public class CSSOutputCache : OutputCacheAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     base.OnResultExecuting(filterContext); 
     filterContext.HttpContext.Response.ContentType = "text/css"; 
    } 
} 

这...

[CSSOutputCache(CacheProfile = "DetailsCSS")] 
public ActionResult DetailsCSS(string version, string id) 
{ 
    // Do something with the version and id here.... bla bla 
    return PartialView("_css"); 
} 
+0

谢谢!!! .. actionfilter实际上做到了! – David 2009-11-19 22:12:01

+0

我更喜欢CSSOutputCacheAttribute版本(请注意,您的示例缺少类名称末尾的属性)。我已经测试过它,它可以工作,并且很高兴看到:)。 – Nashenas 2013-10-24 18:41:41

-1

尝试设置VaryByContentEncoding以及VaryByParam时。

+0

没有,那不是它.. – David 2009-11-18 13:09:26

+2

哎呀。是的,那是行不通的。 ContentType!= ContentEncoding !!对不起这是我的错。 – PatrickSteele 2009-11-18 14:53:20

12

这可能是ASP.NET MVC中的一个错误。 它们在内部有一个叫做OutputCachedPage的类型,它来源于Page。当OnResultExecuting叫上OutputCacheAttribute他们创造这种类型的实例,并调用ProcessRequest(HttpContext.Current),最终调用SetIntrinsics(HttpContext context, bool allowAsync),设置像这样的ContentType:

HttpCapabilitiesBase browser = this._request.Browser; 
this._response.ContentType = browser.PreferredRenderingMime; 

这里有一个修复:

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; 
    } 
} 
+0

'filterContext.IsChildAction'检查的意义是什么? – 2014-11-18 11:30:59