2009-08-13 4 views
1

私は、セッションを頻繁に使用してページ単位のデータを追跡するASP.NETアプリケーションを修正しています。問題の1つは、セッションがページ間で流出することです。ViewStateのようなセッションを使用する

  • データは、だから私がしたい

前後に各ポストバックを送信するためにあまりにも多くのデータがあり

  • 直列化可能ではありません。

    ViewStateのは除いて、より良い解決策になります:

    • セッションデータのページキーを作成します(つまり、非表示のフィールドにランダムなGUIDを固定します)。
    • 部分セッションデータを期限切れにするための良い方法はあり全体的なセッションが

    アクティブであっても捨てられたページからデータを期限切れ?

  • +0

    もう少し情報が有用であろう。各ページに同じデータ構造を保存しようとしていますか、ページごとに一意のデータ構造を保存しようとしていますか?ユーザーが離れた後にセッションデータがハングアップするのはなぜ問題なのですか? –

    +0

    @Christian Hayter彼の質問は、いくつかのページが同じセッションキーを使用することを暗示しています。したがって、ページBのために意図されたデータは、ページBが見つけるためにセッション中に残されている。 – AaronSieb

    +0

    AaronSiebが正しいです。 – Korey

    答えて

    2

    次の一時保管場所が用意されています

    1. セッション。これは、ユーザーの周りを回って、クッキーを使用します。取得するためにURLパラメータを使用するように設定できます。セッションは、Webサーバー、SQL Server、または状態サーバーのプロセス(inproc)に格納されるように構成することもできます。 InProcは任意のデータ型を格納できますが、他の型は型の直列化が必要です。
    2. キャッシュ。キャッシュに格納されたデータは、セッション内の任意のユーザーが使用できるようになっています。これは、オブジェクトがキーを介して取得可能であるため、セッションと同様に機能します。キャッシュの優れた機能の1つは、物事の保管期間を制御でき、期限が切れたときにイベントを消費することができることです。ここには何も保存することができますが、Webファームで使用する際に問題が発生する可能性があります。
    3. HttpContext。これは現在の要求に適用されます。リクエストには、Webサービス呼び出し、HTMLを取得するWebページを取得する呼び出し、またはイメージを返すサービスへの呼び出しがあります。何でもここに保存できます。
    4. ViewState。ビューステートはページにスコープが設定されています。シリアル化可能である必要があります。

    キャッシュを調べることができます。 Webファームを使用している場合は動作しませんが、セッションにマップするキーとして何らかの種類のGUIDを使用できます。

    +0

    キャッシュは、セッションが持続するように20分程度かかることが保証されている可能性があります。 – Korey

    +0

    私が使用したキャッシュコードは次のとおりです。 Cache.Insert(key、value、null、System.Web.Caching.Cache.NoAbsoluteExpiration、New TimeSpan(0、20、0)、System.Web.Caching.CacheItemPriority.NotRemovable 、 ヌル); – Korey

    +0

    CacheItemPriority.NotRemovableは、キャッシュがメモリ不足のためにデータを削除しないようにします。 – Korey

    0

    おそらく各ページで!IsPostBackまたはベースページを通じて、そのページに関係のないセッションデータへのすべての参照を無効にすることができます。これは、ユーザーがサイトの別のページに行くたびにデータを「期限切れにする」でしょう。

    ユーザーがサイトを離れたり、アクティブになったりした場合、セッションが終了するまではあまりできませんが、このシナリオではユーザーあたりセッションデータは1ページ分しかありません。

    +0

    私は複数のページを閲覧できるようにしたいのですが(同じページですが、リクエストデータは異なります)。私は、あるページが自動的に別のページのセッションデータを破壊しないようにしたい、私はそれが期限切れになることができます。 – Korey

    1

    私はおそらくそれをこのようにします:

    1. は、あなたが特定のページになりたい状態情報を格納するオブジェクトを作成します。異なるページに異なる情報が必要な場合は、複数のクラスを作成します。
    2. このオブジェクトを単一のセッションキーに格納します。Session ["PageSpecific"];例えば。
    3. System.Web.UI.Pageから継承するクラスを作成します。
    4. 基本クラスのOnLoadイベントで、ページがポストバックを実行していない場合はセッションキーをクリアします。
    5. セッションオブジェクトにデータを読み込むためのオーバーロード可能なメソッドを作成して呼び出します。
    6. 各ページのSystem.Web.UI.Pageから継承する代わりに、新しい基本クラスを継承します。

    このような何か(警告:エア・コードは、構文エラーを含んでいてもよい):

    public class PageBase 
        : System.Web.UI.Page 
    { 
        protected overrides OnInit(System.EventArgs e) { 
         base.OnInit(e); 
    
         if(!this.IsPostBack) { 
          Guid requestToken = System.Guid.NewGuid(); 
          ViewState["RequestToken"] = requestToken; 
    
          Session["PageSpecific" & requestToken.ToString()] = InitializePageSpecificState(); 
         } 
        } 
    
        protected virtual object InitializePageSpecificState() { 
         return new GenericPageState(); 
        } 
    
        //You can use generics to strongly type this, if you want to. 
        protected object PageSpecificState { 
         get { 
          return Session["PageSpecific" & ViewState["RequestToken"].ToString()]; 
         } 
        } 
    } 
    
    +0

    これは前の回答と同じ問題があります。私の質問は十分にはっきりしていないかもしれません。 一部のユーザーがDefault.aspxを複数のタブで異なる要求データ(または同じもの)で表示している場合があります。私はそれぞれが独自のサーバー側のストレージスペースを持つことを望んでいます。 – Korey

    +0

    @Korey元の質問に編集するのは良いことです。また、簡単に解決できます:初期ロード時に何らかの形式のトークン(Guidなど)を生成します。それをセッションキーに追加します(Session ["PageSpecific"&requestToken])。 ViewStateにキーを格納します。 – AaronSieb

    +0

    @Korey複数のタブを開くことを可能にする主な難点は、セッション全体が満了するまでリクエストからセッションをクリーンアップできないことです。これはあなたのサイズに応じて問題になる場合もあれば、問題でない場合もありますユーザーベース。 – AaronSieb

    関連する問題