16

对于我当前的项目,有必要生成动态 CSS ......

所以,我有一个部分视图,它用作 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/html”,而不是“text/css”...当我删除它时,它按预期工作......

所以,对我来说,OutputCache 似乎没有在这里保存我的“ContentType”设置......有什么办法解决这个问题吗?

谢谢

4

3 回答 3

20

您可以使用在缓存发生后执行的您自己的 ActionFilter 覆盖 ContentType。

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

或者(我还没有尝试过)但是用 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");
}
于 2009-11-18T20:28:09.970 回答
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;
   }
}
于 2009-11-18T19:07:44.033 回答
-1

尝试设置 VaryByContentEncoding 以及 VaryByParam。

于 2009-11-18T12:49:15.883 回答