2011-07-21 22 views
5

私は非常に単純な操作をしようとしています...ユーザーがグループを選択するドロップダウンのあるサイトがあります。その後、ユーザは、メニューからクエリ文字列引数を使用してサイトをナビゲートする。だから私はキャッシングをクエリ文字列に依存させたい - これはうまくいくようだ。また、キャッシュが選択したグループに依存するようにしたい。BOTHを使用した出力キャッシングvarybyparamとvarybycustom

しかし、クエリ文字列が空の場合、どちらのキャッシュ要素も機能していないように見えます。ページは、最後に選択したグループのバージョンであってもかまいません。私のキャッシュディレクティブは次のようになります。

<%@ OutputCache Duration="300" VaryByCustom="currentAtomId" VaryByParam="documentId;folderId;sectionId;renderMode;typeId" %> 

マイvaryByCustomコードは次のようになります。

public override string GetVaryByCustomString(HttpContext context, string custom) 
{ 
    switch (custom) 
    { 
     case "currentAtomId": 
      var currentAtomId = SecurityManifold.Create().CurrentAtomId; 

      var returnString = currentAtomId == null ? Guid.NewGuid().ToString() : currentAtomId.ToString(); 

      return returnString; 

     default: 
      throw new ArgumentException(string.Format("Argument '{0}' is not a valid cache argument.", custom)); 
    } 
} 

CurrentAtomIdへの呼び出しはこれに沸く:最後に

public static int? GetCurrentAtomIdFromContext(HttpContext context) 
{ 
    int entityId; 

    if (context.Session == null) 
    { 
     throw new InvalidOperationException("Session is null"); 
    } 

    var sessionEntityId = context.Session["CurrentEntityId"]; 

    if (sessionEntityId == null || string.IsNullOrEmpty(sessionEntityId.ToString())) 
    { 
     return null; 
    } 

    if (!int.TryParse(sessionEntityId.ToString(), out entityId)) 
    { 
     return null; 
    } 

    return entityId; 
} 

、指定したコードをCurrentEntityIdは次のとおりです。

var selectedEntityId = this.lstSecurityEntities.SelectedValue; 

    if (string.IsNullOrEmpty(selectedEntityId)) 
    { 
     return; 
    } 

    Session["CurrentEntityId"] = selectedEntityId; 

    var possibleQueryString = Request.QueryString.ToString(); 

    if (!string.IsNullOrEmpty(possibleQueryString)) 
    { 
     possibleQueryString = "?" + possibleQueryString; 
    } 

    Response.Redirect("default.aspx" + possibleQueryString); 

私はうんざりです。いかなる考えも認められるだろう。

答えて

6

最終的には、出力キャッシュをPAGEレベル(コントロールレベルではなく)に置くと、そのセッションは利用できず、例外がスローされます。この例外はグローバル・エラー・ハンドラの上でグローバルで発生しているため、サイレントで失敗します。私は結局、VaryByCustomStringとResponse.Write-ingのキャッシュキー生成コードの周りにtry-catchブロックをラップすることでこれを理解しました。

どのような場合でも、解決策はコントロールレベルでキャッシュを実装することです。残念ながら、ページの各部分が連携しているため、残念ながらもっと多くの作業が必要になりますが、キャッシングなしより優れています。私はこれが他の誰かを救うのに役立つことを願っています

ボトムライン:global.asaxのvaryByCustomStringの場合 - セッションはページレベルでキャッシュすると利用できません。

関連する問題