2012-01-23 13 views
11

Mam ActionResult, który jest buforowany.HttpResponse.RemoveOutputCacheItem nie działa

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

Dobrą częścią jest to, że działa pamięć podręczna. Po pierwszym załadowaniu wynik jest pokazywany bez żadnego opóźnienia 4 sekund.

Należy jednak wyczyścić pamięć podręczną po wprowadzeniu pewnych zmian w tym produkcie.

próbowałem wyczyścić pamięć podręczną robi tak:

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

Próbowałem też wywołać metodę RemoveCache zarówno z Ajax i pełnego odświeżania strony, a nie z nimi pracuje.

Co mogę zrobić? Gdzie jest problem?

enter image description here

Odpowiedz

14

W RemoveOutputCacheItem działa tylko z parametrów trasy, nie string zapytanie. Więc można zmodyfikować definicję trasy:

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

Teraz można użyć metody 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"); 
} 

UPDATE:

Oto mój przypadek testowy:

Kontroler:

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

View (~/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 } 
) 

Częściowy widok (~/Views/Home/_Foo.cshtml):

@model string 
@Model 

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

UPDATE 2:

Po wyświetleniu kodu wydaje się, że używasz pomocnika Html.RenderAction, a ProductPreview jest działaniem podrzędnym. Akcje podrzędne nie są przechowywane w tej samej pamięci podręcznej co zwykłe widoki, a pomocnik HttpResponse.RemoveOutputCacheItem nie działa w ogóle z buforowanymi działaniami podrzędnymi. Jeśli przyjrzysz się uważnie w poprzednim przykładzie, zobaczysz, że użyłem standardowych linków do akcji ProductPreview.

Obecnie to, co próbujesz osiągnąć, nie jest możliwe w ASP.NET MVC 3. Jeśli chcesz użyć buforowania wyjścia pączków, poleciłbym Ci following article. Mam nadzieję, że ta funkcjonalność zostanie dodana w ASP.NET MVC 4.

+1

Próbowałem ustawić trasę w pliku Global.asax jak ten "{kontroler}/{akcja}/{product_Id}" i nadal nie działa. Próbowałem również z VaryByCustom = "product_Id" i też nie działa. Czy ma coś wspólnego z tym, że jest ParialView? – Catalin

+0

@RaraituL, nie, nie sądzę, że jest to związane z faktem, że jest to częściowy widok. Zaktualizowałem swoją odpowiedź, aby podać pełną wersję testową, która zadziałała. –

+0

Stworzyłem projekt testowy z tym samym scenariuszem, to nie działa, nie rozumiem dlaczego. Usunąłem nawet parametr z ActionResult. Czy jest ustawienie web.config? czy muszę przechowywać pamięć podręczną na serwerze, czy zmienić niektóre ustawienia domyślne? Zamieszczam kilka zdjęć – Catalin