2009-11-18 79 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