Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重写ASP.NET缓存策略并将缓存控制设置为公共_C#_Asp.net_Asp.net Mvc_Caching - Fatal编程技术网

C# 重写ASP.NET缓存策略并将缓存控制设置为公共

C# 重写ASP.NET缓存策略并将缓存控制设置为公共,c#,asp.net,asp.net-mvc,caching,C#,Asp.net,Asp.net Mvc,Caching,我想在我的ASP.NET(MVC)应用程序中将缓存控制标题设置为public。问题在于,有一些代码(我无法更改)以前设置了如下缓存策略: var response = htmlHelper.ViewContext.HttpContext.Response; response.Cache.SetExpires(System.DateTime.UtcNow.AddDays(-1)); response.Cache.SetValidUntilExpire

我想在我的ASP.NET(MVC)应用程序中将
缓存控制
标题设置为
public
。问题在于,有一些代码(我无法更改)以前设置了如下缓存策略:

        var response = htmlHelper.ViewContext.HttpContext.Response;
        response.Cache.SetExpires(System.DateTime.UtcNow.AddDays(-1));
        response.Cache.SetValidUntilExpires(false);
        response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        response.Cache.SetCacheability(HttpCacheability.NoCache);
        response.Cache.SetNoStore();
我找不到一种方法在以后重写它,因为无论我如何尝试设置缓存控制,上述操作都会生效。例如,以下两种情况都不能阻止以前禁用的缓存:

        httpContext.Response.Headers["Cache-Control"] = "public";
        var cache = httpContext.Response.Cache;
        cache.SetExpires(cacheItem.ValidUntilUtc);
        cache.SetValidUntilExpires(true);
        cache.SetRevalidation(HttpCacheRevalidation.None);
        cache.SetCacheability(HttpCacheability.Public);
        cache.SetMaxAge(cacheItem.ValidUntilUtc - _clock.UtcNow);

是否有办法覆盖或重置缓存策略?

在第一个代码示例中,缓存属性似乎是在HTML帮助程序中设置的,而HTML帮助程序很可能以某种方式呈现在视图上。我猜您尝试覆盖属性的时间太早,然后在视图渲染时被覆盖

显然,更改设置这些头的代码是最好的。如果你绝对不能,我看到了一些前进的路线:

  • 不要立即从控制器返回视图。您可能会遇到以下情况:

    public ActionResult MyAction() {
        // code here
    
        return View();
    }
    
    将其转换为,然后可以尝试覆盖视图中的缓存:

    public ActionResult MyAction() {
        // code here
    
        var result = View();
        ResetCaching();
        return result;
    }
    
  • 如果这不起作用,请在控制器中使用
    OnResultExecuted
    OnActionExecuted
    捕获视图何时完成执行或操作何时执行,并尝试在执行视图和/或操作后但在释放控制器之前覆盖缓存。

    不必重写控制器上的实际事件,您可以实现一个可以保持代码更干净并允许在多个位置重用代码的方法

  • 在绝对最坏的情况下,请在
    global.asax
    文件中使用
    Application\u PreSendRequestHeaders
    事件,如果请求满足重置缓存的要求,请在将头发送到浏览器之前修改头。此方法将使您检查通过应用程序的每个请求


  • 显然这是不可能的,因为
    HttpCachePolicy
    会主动阻止您设置“更高”的可访问性,即如果您在设置NoCache后尝试设置Public,则不会发生任何事情

    似乎唯一的黑客方法是使用私有反射并调用内部
    Reset
    方法,如下所示:

            var cache = httpContext.Response.Cache;
            var cachePolicy = (HttpCachePolicy)typeof(HttpCachePolicyWrapper).InvokeMember("_httpCachePolicy", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField, null, cache, null);
            typeof(HttpCachePolicy).InvokeMember("Reset", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, cachePolicy, null);
            cache.SetCacheability(HttpCacheability.Public);
    

    谢谢,但这不是问题所在。顺序正确,即我的代码在导致问题的代码之后运行(它实际上是在OnResultExecuted中的结果过滤器中执行的)。导致我的尝试失败的原因是,一旦设置为NoCache HttpCachePolicyBase,将不允许您启用缓存。@Piedone我不知道它阻止您重置它,对此表示抱歉。在阅读了源代码之后,我没有看到一个官方的方法来重置它。它向您展示了如果您对使用反射感兴趣,如何修补策略的内部属性以重置内容。谢谢,是的,这就是我最后要做的。将添加一个答案。