2009-11-18 13 views
15

für ein aktuelles Projekt notwendig es ist dynamisch CSS zu generieren ...ASP.NET MVC: Problem mit Output

Also, ich habe eine Teilansicht, die als CSS Zusteller dient ... Der Controller Code sieht wie folgt aus :

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

das Ausgabe-Cache-Profil wie folgt aussieht:

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

das Problem ist: Wenn ich die Outputleitung verwenden ([Output (CacheProfile = "DetailsCSS")]), die Reaktion des Gehalt an Geben Sie "Text/h tml ", anstelle von" text/css "... wenn ich es entferne, funktioniert es wie erwartet ...

Also, für mich scheint es, dass der OutputCache meine" ContentType "Einstellung hier nicht speichert .. Gibt es einen Weg dahin?

Dank

Antwort

19

Sie könnte den ContentType mit einem eigenen ActionFilter überschreiben, der ausgeführt wird, nachdem der Cache aufgetreten ist.

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

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

Und dann dieses Attribut nach dem OutputCache aufrufen.

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

Oder (und ich habe nicht versucht), aber die „OutputCacheAttribute“ Klasse mit einer CSS-spezifischen Implementierung außer Kraft setzen. So etwas wie dies ...

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

und diese ...

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

danke !!! .. der actionfilter hat es tatsächlich geschafft! – David

+0

Ich würde die Version CSSOutputCacheAttribute bevorzugen (beachten Sie, Ihr Beispiel fehlt das Attribut am Ende des Klassennamens). Ich habe es getestet, es funktioniert, und es ist schön zu sehen :). – Nashenas

-1

Versuchen Sie, die VaryByContentEncoding sowie VaryByParam Einstellung.

+0

nein, das war es nicht .. – David

+2

Oops. Ja, das würde nicht funktionieren. ContentType! = ContentEncoding !! Entschuldigung, mein fehler. – PatrickSteele

12

Dies könnte ein Fehler in ASP.NET MVC sein. Intern haben sie einen Typ OutputCachedPage, der von Page abgeleitet ist. Wenn OnResultExecuting auf OutputCacheAttribute aufgerufen wird, schaffen sie eine Instanz dieses Typs und rufen ProcessRequest(HttpContext.Current), die SetIntrinsics(HttpContext context, bool allowAsync) schließlich Anrufe, die der Content wie folgt setzt:

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

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

Welche Bedeutung hat die 'filterContext.IsChildAction' Prüfung? –