Asp.net mvc 3 mvc3 OutputCache RemoveOutputCacheItem渲染

Asp.net mvc 3 mvc3 OutputCache RemoveOutputCacheItem渲染,asp.net-mvc-3,outputcache,Asp.net Mvc 3,Outputcache,我做了研究,但没有找到任何答案 我在母版页中使用Html.RenderAction(用特定于用户权限的链接呈现页眉)。操作用OutputCache修饰,返回部分控制并按预期缓存 当事件发生时(假设权限已更改),我希望以编程方式使缓存的部分控件无效 我正在尝试使用RemoveOutputCacheItem方法。它将路径作为参数。我正在尝试设置Html.RenderAction中使用的操作的路径。这并不会使行动无效 如何以编程方式使操作无效 感谢子操作的缓存存储在属性中。问题是,为子操作生成ID并将

我做了研究,但没有找到任何答案

我在母版页中使用Html.RenderAction(用特定于用户权限的链接呈现页眉)。操作用OutputCache修饰,返回部分控制并按预期缓存

当事件发生时(假设权限已更改),我希望以编程方式使缓存的部分控件无效

我正在尝试使用RemoveOutputCacheItem方法。它将路径作为参数。我正在尝试设置Html.RenderAction中使用的操作的路径。这并不会使行动无效

如何以编程方式使操作无效


感谢

子操作的缓存存储在属性中。问题是,为子操作生成ID并将其存储在此对象中的API不是公共的(为什么是Microsoft??)。因此,如果您尝试循环此集合中的对象,您将发现它也将包含子操作的缓存值,但您将无法识别它,除非您对用于生成密钥的算法进行反向工程,该算法看起来像这样(如Reflector所示):

因此,您可以执行以下疯狂操作:

public ActionResult Invalidate()
{
    OutputCacheAttribute.ChildActionCache = new MemoryCache("NewDefault");
    return View();
}
这显然会使所有缓存的子操作失效,这些子操作可能不是您想要的,但我担心这是唯一的方法,当然不是反向工程密钥生成:-)

@Microsoft,我请求您提供ASP.NET MVC 4.0:

  • 介绍除了甜甜圈孔缓存之外,还可以进行甜甜圈缓存
  • 引入一种可能性,使缓存控制器操作的结果容易过期(比
    响应更MVCish。RemoveOutputCacheItem
  • 引入容易使缓存的子操作的结果过期的可能性
  • 如果你做1。然后,显然引入了使缓存的甜甜圈部分过期的可能性

  • 您可能希望以另一种方式处理此问题。您可以创建一个定制的AuthorizeAttribute——它只允许所有人——并添加覆盖OnCacheValidation方法以合并您的逻辑。如果基本OnCacheValidation返回HttpValidationStatus.Valid,则检查状态是否已更改,如果已更改,则返回HttpValidationStatus.Invalid

    public class PermissionsChangeValidationAttribute : AuthorizeAttribute
    {
         public override OnAuthorization( AuthorizationContext filterContext )
         {
            base.OnAuthorization( filterContext );
         }
    
         public override HttpValidationStatus OnCacheAuthorization( HttpContextBase httpContext )
         {
             var status = base.OnCacheAuthorization( httpContext );
             if (status == HttpValidationStatus.Valid)
             {
                ... check if the permissions have changed somehow
                if (changed)
                {
                    status = HttpValidationStatus.Invalid;
                }
             }
             return status;
         }
    }
    

    请注意,如果需要跟踪以前的状态,可以在缓存验证过程中传递其他数据,但必须在基类中复制一些代码,并添加自己的自定义缓存验证处理程序。您可以从我关于创建自定义授权属性的博文中找到一些关于如何执行此操作的想法:

    听起来像是一个解决方案。但是它非常难看,因为它迫使我将事件列表存储在某个位置,然后从这里查询列表,以选择性地使HttpValidationStatus…@user无效-如果可能,我会存储缓存项的条件,然后简单地检查这些条件是否已更改。查看我博客文章中的
    SetCachePolicy
    调用。额外的数据参数可用于存储当前条件。您需要一个CacheValidationHandler,当发出缓存请求时,它可以解包这些内容并将它们与当前条件进行比较。@用户--您可能还想看看是否可以使OutputCacheAttribute上的VaryByCustom属性为您工作。也许有一个方法可以为每一组条件生成一个唯一的值?我使用VaryByCustom返回UserId。@user-您可以扩展它来封装可能发生更改的其他内容吗?比如说一个封装用户id及其权限的字符串?“134:EditUser:ViewUser:DeleteUser”--如果任何权限发生更改或是其他用户,您将获得一个未缓存的页面。我想知道如何循环您提到的集合?@user662589,使用
    foreach
    循环:
    foreach(OutputCacheAttribute.ChildActionCache中的var项){…}
    @Darin-你的祈祷已经得到了回答:-)开源MvcDonutCaching NuGet包涵盖了第1-4点@TheFlowerGuy:将该链接作为答案发布。我在这里找到它纯属偶然!这应该是一个答案!
    public class PermissionsChangeValidationAttribute : AuthorizeAttribute
    {
         public override OnAuthorization( AuthorizationContext filterContext )
         {
            base.OnAuthorization( filterContext );
         }
    
         public override HttpValidationStatus OnCacheAuthorization( HttpContextBase httpContext )
         {
             var status = base.OnCacheAuthorization( httpContext );
             if (status == HttpValidationStatus.Valid)
             {
                ... check if the permissions have changed somehow
                if (changed)
                {
                    status = HttpValidationStatus.Invalid;
                }
             }
             return status;
         }
    }