ASP.NET MVC:OutputCache的问题

时间:2021-06-30 03:51:30

for my current project it's necessary to generate dynamic CSS...

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

So, i have a partial view which serves as a CSS deliverer... The controller code looks like this:

所以,我有一个局部视图作为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");
    }

The output cache profile looks like:

输出缓存配置文件如下所示:

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

The problem is: When i use the OutputCache line ([OutputCache(CacheProfile = "DetailsCSS")]), the response is of content type "text/html", instead of "text/css"... when i remove it, it works as expected...

问题是:当我使用OutputCache行([OutputCache(CacheProfile =“DetailsCSS”)])时,响应的内容类型为“text / html”,而不是“text / css”...当我删除它时,它按预期工作......

So, for me it seems that the OutputCache doesn't save my "ContentType" setting here... is there any way around this?

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

Thanks

谢谢

3 个解决方案

#1


19  

You could overwrite the ContentType with your own ActionFilter that executes after the cache has occurred.

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

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

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

And then call that attribute after the OutputCache.

然后在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 (and I haven't tried this) but override the "OutputCacheAttribute" class with a CSS specific implementation. Something like this...

或者(我还没试过)但是使用CSS特定的实现覆盖“OutputCacheAttribute”类。这样的东西......

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

and this...

和这个...

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

#2


12  

This could be a bug in ASP.NET MVC. Internally they have a type called OutputCachedPage that derives from Page. When OnResultExecuting is called on OutputCacheAttribute they create an instance of this type and call ProcessRequest(HttpContext.Current), which eventually calls SetIntrinsics(HttpContext context, bool allowAsync) that sets the ContentType like this:

这可能是ASP.NET MVC中的一个错误。在内部,它们有一个名为OutputCachedPage的类型,它源自Page。当在OutputCacheAttribute上调用OnResultExecuting时,他们创建一个这种类型的实例并调用ProcessRequest(HttpContext.Current),它最终调用SetIntrinsics(HttpContext context,bool allowAsync)来设置ContentType,如下所示:

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

Here's a 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;
   }
}

#3


-1  

Try setting the VaryByContentEncoding as well as VaryByParam.

尝试设置VaryByContentEncoding以及VaryByParam。

#1


19  

You could overwrite the ContentType with your own ActionFilter that executes after the cache has occurred.

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

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

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

And then call that attribute after the OutputCache.

然后在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 (and I haven't tried this) but override the "OutputCacheAttribute" class with a CSS specific implementation. Something like this...

或者(我还没试过)但是使用CSS特定的实现覆盖“OutputCacheAttribute”类。这样的东西......

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

and this...

和这个...

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

#2


12  

This could be a bug in ASP.NET MVC. Internally they have a type called OutputCachedPage that derives from Page. When OnResultExecuting is called on OutputCacheAttribute they create an instance of this type and call ProcessRequest(HttpContext.Current), which eventually calls SetIntrinsics(HttpContext context, bool allowAsync) that sets the ContentType like this:

这可能是ASP.NET MVC中的一个错误。在内部,它们有一个名为OutputCachedPage的类型,它源自Page。当在OutputCacheAttribute上调用OnResultExecuting时,他们创建一个这种类型的实例并调用ProcessRequest(HttpContext.Current),它最终调用SetIntrinsics(HttpContext context,bool allowAsync)来设置ContentType,如下所示:

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

Here's a 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;
   }
}

#3


-1  

Try setting the VaryByContentEncoding as well as VaryByParam.

尝试设置VaryByContentEncoding以及VaryByParam。