HttpResponse.RemoveOutputCacheItem не работает - PullRequest
12 голосов
/ 23 января 2012

У меня есть 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));
}

Хорошая часть заключается в том, что кэш работает.После первой загрузки результат отображается без задержки в 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");
}

Я также пытался вызвать метод RemoveCache как с ajax, так и с полным обновлением страницы, и ни один из них не работает.В чем проблема?

enter image description here

1 Ответ

16 голосов
/ 23 января 2012

RemoveOutputCacheItem работает только с параметрами маршрута, а не строкой запроса.Таким образом, вы можете изменить определение маршрута:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{product_Id}",
    new { controller = "Home", action = "Index" }
);

Теперь вы можете использовать метод 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");
}

ОБНОВЛЕНИЕ:

Вот мой тестовый пример:

Контроллер:

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

Вид (~/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 }
)

Частичный вид (~/Views/Home/_Foo.cshtml):

@model string
@Model

и в 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 }
    );
}

ОБНОВЛЕНИЕ 2:

Теперь, когда вы показали свой код, кажется, что вы используете помощник Html.RenderAction и ProductPreviewэто детское действие.Дочерние действия не хранятся в том же кэше, что и обычные представления, и помощник HttpResponse.RemoveOutputCacheItem вообще не работает с кэшированными дочерними действиями.Если вы внимательно посмотрите в моем предыдущем примере, вы увидите, что я использовал стандартные ссылки для действия ProductPreview.

В настоящее время то, что вы пытаетесь достичь, невозможно в ASP.NET MVC 3. Если вы хотитеиспользуйте кэширование пончиков, я бы порекомендовал вам следующую статью .Надеемся, что эта функциональность будет добавлена ​​в ASP.NET MVC 4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...