2009-11-18 2 views
15

для моего текущего проекта необходимо для создания динамического CSS ...ASP.NET MVC: Проблема с OutputCache

Итак, у меня есть частичный вид, который служит в качестве 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")]), ответ содержания type "text/html "вместо" text/css "... когда я удаляю его, он работает так, как ожидается ...

Итак, для меня кажется, что OutputCache не сохраняет здесь настройку« ContentType ». .. есть ли какой-либо путь вокруг этого?

Благодаря

ответ

19

Вы может перезаписать ContentType с помощью собственного ActionFilter, который выполняется после того, как произошел кеш.

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

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

И затем вызывается этот атрибут после 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"); 
} 

Или (и я не пробовал), но переопределить класс «OutputCacheAttribute» с CSS конкретной реализации. Что-то вроде этого ...

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

+0

Я бы предпочел версию CSSOutputCacheAttribute (обратите внимание: в вашем примере отсутствует атрибут в конце имени класса). Я тестировал его, он работает, и приятно смотреть на :). – Nashenas

-1

Try установки VaryByContentEncoding, а также VaryByParam.

+0

нет, это было не так .. – David

+2

К сожалению. Да, это не сработает. ContentType! = ContentEncoding !! Извини, я виноват. – PatrickSteele

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? –

Смежные вопросы