2009-11-18 17 views
15

per il mio progetto attuale è necessario generare dinamica CSS ...ASP.NET MVC: problema con OutputCache

così, ho una vista parziale che serve come un liberatore CSS ... Il codice di controllo si presenta come questo :

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

il profilo di cache di output assomiglia:

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

il problema è: Quando uso la linea OutputCache ([OutputCache (CacheProfile = "DetailsCSS")]), la risposta è di contenuti digita "text/h tml ", invece di" text/css "... quando lo rimuovo, funziona come previsto ...

Quindi, per me sembra che OutputCache non salvi l'impostazione" ContentType "qui .. . C'è un modo per aggirare questo?

Grazie

risposta

19

È potrebbe sovrascrivere il ContentType con il proprio ActionFilter che viene eseguito dopo che si è verificata la cache.

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

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

E quindi chiamare tale attributo dopo 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 (e non ho provato questo), ma sostituire la classe "OutputCacheAttribute" con una specifica implementazione di CSS. Qualcosa di simile ...

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

e questo ...

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

grazie !!! .. il filtro azione lo ha fatto davvero! – David

+0

Preferirei la versione CSSOutputCacheAttribute (nota, il tuo esempio manca l'Attributo alla fine del nome della classe). L'ho provato, funziona, ed è bello guardare :). – Nashenas

-1

impostando il VaryByContentEncoding così come VaryByParam prova.

+0

no, non è vero .. – David

+2

Ops. Sì, non funzionerebbe. ContentType! = ContentEncoding !! Scusa colpa mia. – PatrickSteele

12

Questo potrebbe essere un bug in ASP.NET MVC. Internamente hanno un tipo chiamato OutputCachedPage che deriva da Page. Quando OnResultExecuting è chiamato OutputCacheAttribute creano un esempio di questo tipo e chiamano ProcessRequest(HttpContext.Current), che alla fine chiama SetIntrinsics(HttpContext context, bool allowAsync) che imposta le ContentType come questo:

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

Ecco una correzione:

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

Qual è il significato del controllo 'filterContext.IsChildAction'? –