2009-11-18 6 views
15

pour mon projet actuel, il est nécessaire de générer CSS dynamique ...ASP.NET MVC: Problème avec OutputCache

Alors, j'ai une vue partielle qui sert de Libérateur CSS ... Le code du contrôleur ressemble à ceci :

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

le profil de cache de sortie ressemble:

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

le problème est le suivant: Quand j'utilise la ligne OutputCache ([OutputCache (CacheProfile = "DetailsCSS")]), la réponse est contenu tapez "text/h tml ", au lieu de" text/css "... quand je l'enlève, il fonctionne comme prévu ...

Donc, pour moi, il semble que le OutputCache n'enregistre pas mon" ContentType "réglage ici .. Y at-il un moyen de contourner cela?

Merci

Répondre

19

Vous pourrait remplacer le ContentType avec votre propre ActionFilter qui s'exécute après que le cache s'est produit.

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

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

Ensuite, appelez cet attribut après 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"); 
} 

Ou (et je ne l'ai pas essayé) mais remplacer la classe « OutputCacheAttribute » avec une mise en œuvre spécifique CSS. Quelque chose comme ça ...

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

et ce ...

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

merci !!! .. le actionfilter l'a fait! – David

+0

Je préférerais la version CSSOutputCacheAttribute (notez que votre exemple ne contient pas l'attribut à la fin du nom de la classe). Je l'ai testé, ça marche, et c'est sympa à regarder :). – Nashenas

-1

Essayez de régler les VaryByContentEncoding ainsi que VaryByParam.

+0

non, c'était pas .. – David

+2

Oops. Oui, ça ne marcherait pas. ContentType! = ContentEncoding !! Désolé mon mauvais. – PatrickSteele

12

Cela peut être un bogue dans ASP.NET MVC. En interne, ils ont un type appelé OutputCachedPage qui dérive de Page. Lorsque OnResultExecuting est appelé OutputCacheAttribute ils créent une instance de ce type et appellent ProcessRequest(HttpContext.Current), qui appelle finalement SetIntrinsics(HttpContext context, bool allowAsync) qui définit les ContentType comme celui-ci:

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

Voici une solution:

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

Quelle est la signification du contrôle 'filterContext.IsChildAction'? –