2012-01-23 44 views
11

私はキャッシュされたActionResultを持っています。HttpResponse.RemoveOutputCacheItemが機能していません

[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メソッドを呼び出そうとし、それらの非が働いています。

私は何ができますか?問題はどこだ?

enter image description here

答えて

14

のみルートパラメーターではなく、クエリ文字列と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"); 
} 

UPDATE:

コントローラ:

ここに私のテストケースです。

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

UPDATE 2:

コードを表示したので、Html.RenderActionヘルパーを使用していて、ProductPreviewは子アクションです。子のアクションは通常のビューと同じキャッシュには格納されず、キャッシュされた子のアクションではHttpResponse.RemoveOutputCacheItemヘルパーはまったく機能しません。前の例を注意深く見てみると、私はProductPreviewアクションの標準リンクを使用していることがわかります。

現在、達成しようとしていることはASP.NET MVC 3では不可能です。ドーナツ出力キャッシングを使用する場合は、following articleをお勧めします。うまくいけば、この機能はASP.NET MVC 4に追加されます。

+1

この "{controller}/{action}/{product_Id}"のようなGlobal.asaxファイルでルートを設定しようとしましたが、それでも動作しません。私もVaryByCustom = "product_Id"で試していて、どちらも動作していません。 ParialViewという事実と関係がありますか? – Catalin

+0

@RaraituL、いいえ、私はそれが部分的な視点であるという事実に関連しているとは思わない。完全なテストケースを提供するために私の答えを更新しました。 –

+0

私は同じシナリオでテストプロジェクトを作成しましたが、動作していません。理由を理解できません。私はActionResultからパラメータを削除しました。 web.configの設定ですか?サーバーにキャッシュを保存する必要がありますか、またはいくつかのデフォルト設定を変更しますか?私はいくつかの画像を投稿します – Catalin

関連する問題