HttpResponse.RemoveOutputCacheItem不起作用

Cat*_*lin 12 model-view-controller asp.net-mvc caching

我有一个缓存的ActionResult.

[OutputCache(Duration = 3600, VaryByParam = "product_Id")]
public ActionResult ProductPreview(Guid product_Id)
{
     // just for testing the cache
     System.Threading.Thread.Sleep(4000);
     return PartialView("ProductPreview", _repository.CreateProductModel(product_Id));
}
Run Code Online (Sandbox Code Playgroud)

好的部分是缓存正在运行.在第一次加载后,结果显示没有任何4秒延迟.

但是,我需要在对该产品进行一些更改时清除缓存.

我试图清除缓存这样做:

public ActionResult RemoveCache()
{
    var url = Url.Action("ProductPreview", "Common");
    // also tried with parameter
    // var url = Url.Action("ProductPreview", "Common", new { @product_Id = "productId" });
    HttpResponse.RemoveOutputCacheItem(url);

    return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)

我还尝试使用ajax和整页刷新调用RemoveCache方法,并且它们都没有工作.

我能做什么?问题出在哪儿?

在此输入图像描述

Dar*_*rov 16

RemoveOutputCacheItem只与路由参数的作品,而不是查询字符串.所以你可以修改你的路线定义:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{product_Id}",
    new { controller = "Home", action = "Index" }
);
Run Code Online (Sandbox Code Playgroud)

现在您可以使用RemoveOutputCacheItem方法:

public ActionResult RemoveCache(Guid product_Id)
{
    var url = Url.Action("ProductPreview", "Common", new { product_Id = product_Id });
    // the url must look like this: /Common/ProductPreview/eeb2fe32-db58-4fc3-87c8-b47480fbe094
    // for the RemoveOutputCacheItem method to work
    HttpResponse.RemoveOutputCacheItem(url);
    return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)

更新:

这是我的测试用例:

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [OutputCache(Duration = 3600, VaryByParam = "product_id")]
    public ActionResult ProductPreview(Guid product_id)
    {
        var model = string.Format(
            "{0} - {1}", 
            product_id, 
            DateTime.Now.ToLongTimeString()
        )
        return PartialView("_Foo", model);
    }

    public ActionResult RemoveCache(Guid product_id)
    {
        var url = Url.Action(
            "ProductPreview", 
            "Home", 
            new { product_id = product_id }
        );
        HttpResponse.RemoveOutputCacheItem(url);
        return RedirectToAction("Index");
    }
}
Run Code Online (Sandbox Code Playgroud)

查看(~/Views/Home/Index.cshtml):

@{
    var productId = Guid.NewGuid();    
}

@Html.ActionLink("product 1", "ProductPreview", new { product_id = Guid.NewGuid() })
<br/>
@Html.ActionLink("product 2", "ProductPreview", new { product_id = productId })
<br/>
@Html.ActionLink("product 3", "ProductPreview", new { product_id = Guid.NewGuid() })
<br />

@Html.ActionLink(
    "clear cache for the second product", 
    "RemoveCache", 
    new { product_id = productId }
)
Run Code Online (Sandbox Code Playgroud)

局部视图(~/Views/Home/_Foo.cshtml):

@model string
@Model
Run Code Online (Sandbox Code Playgroud)

并在global.asax:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{product_id}",
        new { controller = "Home", action = "Index", product_id = UrlParameter.Optional }
    );
}
Run Code Online (Sandbox Code Playgroud)

更新2:

既然您已经显示了代码,那么您似乎正在使用Html.RenderAction帮助程序并且ProductPreview是一个子操作.子操作不与普通视图存储在同一缓存中,并且HttpResponse.RemoveOutputCacheItem帮助程序根本不适用于缓存的子操作.如果仔细查看我之前的示例,您会看到我使用标准链接进行ProductPreview操作.

目前您在ASP.NET MVC 3中无法实现的目标.如果您想使用甜甜圈输出缓存,我建议您阅读以下文章.希望此功能将添加到ASP.NET MVC 4中.