2012-02-25 68 views
2

我有一個ASP.NET MVC應用程序,其中某些資源都是這樣解決的:選擇基於查詢字符串的OutputCache政策

/controller/action/id?revision=123 

修訂參數是可選的:

  • 如果是缺少我做的302重定向到最新版本。我希望這個重定向響應只被緩存一小會兒,或者根本不需要。
  • 如果它存在,我想緩存響應很長一段時間,因爲任何給定的資源修訂都是不可變的。

我第一次嘗試是做這樣的事情:

[OutputCache(Duration=10,Location=OutputCacheLocation.Server)] 
public Action(string id) 
{ 
    long lastRevision = GetLastRevision(id); 
    return RedirectToAction("Action", 
     new { Id = id, revision = lastRevision }); 
} 

[OutputCache(Duration=int.MaxValue,Location=OutputCacheLocation.Server)] 
public Action(string id, long revision) 
{ 
    // ... 
} 

不幸的是,ASP.NET MVC路由似乎並不喜歡方法重載。它希望只有一個Action方法,並帶有一個可選參數(即long? revision),但我無法爲這兩種情況指定不同的緩存策略。

如何根據查詢字符串的存在情況選擇不同的緩存策略?

回答

2

你可以寫一個自定義的方法選擇:

public class RevisionMethodSelectorAttribute : ActionMethodSelectorAttribute 
{ 
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) 
    { 
     var revision = controllerContext.Controller.ValueProvider.GetValue("revision"); 
     var hasRevisionParam = methodInfo.GetParameters().Any(p => string.Equals("revision", p.Name, StringComparison.OrdinalIgnoreCase)); 
     if (revision != null && !string.IsNullOrEmpty(revision.AttemptedValue) && hasRevisionParam) 
     { 
      return true; 
     } 

     if ((revision == null || string.IsNullOrEmpty(revision.AttemptedValue)) && !hasRevisionParam) 
     { 
      return true; 
     } 

     return false; 
    } 
} 

,然後用它裝點2個動作:

[RevisionMethodSelector] 
public ActionResult MyAction(string id) 
{ 
    long lastRevision = GetLastRevision(id); 
    return RedirectToAction("MyAction", new { id = id, revision = lastRevision }); 
} 

[RevisionMethodSelector] 
[OutputCache(Duration = int.MaxValue, Location = OutputCacheLocation.Server, VaryByParam = "revision")] 
public ActionResult MyAction(string id, long revision) 
{ 
    ... 
} 

第一個動作不被緩存。如果請求中沒有修訂參數,它將被拾取,它將簡單地重定向到第二個操作。第二個動作被緩存了很長時間,這個緩存會根據修訂參數值(您沒有的)而變化,並且如果請求中存在修訂參數,則會被自定義方法選擇器選取。

0

事實證明,我已經解決了這個問題,而通過利用302個重定向意識到這一點:顯然302響應不緩存即使你對你的控制器的方法有OutputCache屬性!

因此,這兩種情況都可以通過單個控制器方法處理,[OutputCache(...)]屬性指定爲200個響應執行的操作。

雖然這現在乞討的問題,如果你想要緩存302 ...