2011-01-07 13 views
7

私はasp.netを取得して、viewstateをセッションに格納するのではなく、htmlを拡張します。asp.netを取得する代わりにviewstateをセッションに格納します。

これで、asp.netには、これを行うためにデフォルトのHiddenFieldPageStatePersisterの代わりに使用できるSessionPageStatePersisterが付属しています。どのように私はそれを落とすことについて行くのだろうか? 私は、GetStatePersisterメソッドからSessionPageStatePersisterを返すPageAdapterを作成し、何らかの形でこのpageadapterを使用するようにする必要があると思います。しかし、Page.PageAdapterにはゲッターしかないので、どのように設定するのかは分かりません。

'発言' はここに見出しを参照してください:http://msdn.microsoft.com/en-us/library/system.web.ui.hiddenfieldpagestatepersister.aspx

感謝を!

+0

あなたが考えられていますセッションの代わりにDBにViewStateを格納すると、これは簡単になり、はるかに優れているはずです – Daveo

+0

RPM:viewstateはすでにシリアル化されているため、違いはありません。私のサーバー上のRAMは、オーストラリアのネットワーク接続で両方の方法で100kbのviewstateを送信するよりもずっと高速です。 – Chris

+0

daveo:DbはRAMよりも遅いでしょう。スケーリングは問題ではありません。そのようなウェブサイトではありません。 – Chris

答えて

5

カスタムPageAdapterクラスを使用するには、それを.browserファイルに登録する必要があります。 App_Browsersディレクトリを追加する必要があります(まだ持っていない場合)。次に、次のXMLを含む.browserファイルを追加します。

<browsers> 
    <browser refID="Default"> 
     <controlAdapters> 
      <adapter controlType="System.Web.UI.Page" adapterType="{Your adapter type}" /> 
     </controlAdapters> 
    </browser> 
</browsers> 

{あなたのアダプターの種類}をアダプターの種類に置き換えます。

詳しい情報here

は、この情報がお役に立てば幸いです。

+0

ありがとう、それは私のために働いた。しかし、このメソッドとSessionPageStatePersisterクラスを使用すると、実際にはviewstateのサイズが実際には縮小されませんでした(そして、呼び出されたことを確認するためにブレークポイントを実行しました)。私はそれが単にpagestateを保存していたと思います。ビューステートではなく、本当に大きな節約ではありません。しかたがない。とにかくありがとう! – Chris

8

本当に行いたいですか?問題があります

  1. 個々のページをどのように隔離していますか?もちろん、セッション状態名の前に接頭辞を付けることができます。 Session ["/ default.aspx-Viewstate"]しかし、ユーザーがページの複数のインスタンスを開いているとどうなりますか?
  2. したがって、各ページにGUIDを含む隠しフィールドを配置し、それをキーとして使用します。セッションのサイズが大きくなります。そして成長する。そして成長する。物事を安全に取り除くことができるかどうか、どのように知っていますか?あなたは、これがその後、読んダウン見出しを主張する場合は

は、あなたがする必要があるすべてのページからクラスを派生し、LoadPageStateFromPersistenceMedium()とSavePageStateToPersistenceMedium()をオーバーライドしています。しかし、あなたは自分自身を憎んで、最終的にそれを裂くでしょう。

サーバでHTTP圧縮を有効にしていることを確認してください。代わりに別のものを心配してください。

+1

最後の文が私を笑わせてくれましたが、それはかなり真実です。 gzipはviewstateの世界を補うでしょう。 –

+0

1:組み込みのSessionPageStatePersisterクラス – Chris

+0

2:フェアコールで世話をすると仮定しました。私は何かを考えるだろうと確信しています。多分円形配列か何か。 – Chris

7

価値があるのは、私が手にした大きな画像の問題を解決するために使い終わったコードです:htmlからviewstateを動かす。ちょうどあなたのmypage.aspx.csにこれをポップ:

// Inspired by: http://aspalliance.com/72 
const string ViewStateFieldName = "__VIEWSTATEKEY"; 
const string RecentViewStateQueue = "RecentViewStateQueue"; 
const int RecentViewStateQueueMaxLength = 5; 

protected override object LoadPageStateFromPersistenceMedium() 
{ 
    // The cache key for this viewstate is stored where the viewstate normally is, so grab it 
    string viewStateKey = Request.Form[ViewStateFieldName] as string; 
    if (viewStateKey == null) return null; 

    // Grab the viewstate data from the cache using the key to look it up 
    string viewStateData = Cache[viewStateKey] as string; 
    if (viewStateData == null) return null; 

    // Deserialise it 
    return new LosFormatter().Deserialize(viewStateData); 
} 

protected override void SavePageStateToPersistenceMedium(object viewState) 
{ 
    // Serialise the viewstate information 
    StringBuilder _viewState = new StringBuilder(); 
    StringWriter _writer = new StringWriter(_viewState); 
    new LosFormatter().Serialize(_writer, viewState); 

    // Give this viewstate a random key 
    string viewStateKey = Guid.NewGuid().ToString(); 

    // Store the viewstate in the cache 
    Cache.Add(viewStateKey, _viewState.ToString(), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(Session.Timeout), CacheItemPriority.Normal, null); 

    // Store the viewstate's cache key in the viewstate hidden field, so on postback we can grab it from the cache 
    ClientScript.RegisterHiddenField(ViewStateFieldName, viewStateKey); 

    // Some tidying up: keep track of the X most recent viewstates for this user, and remove old ones 
    var recent = Session[RecentViewStateQueue] as Queue<string>; 
    if (recent == null) Session[RecentViewStateQueue] = recent = new Queue<string>(); 
    recent.Enqueue(viewStateKey); // Add this new one so it'll get removed later 
    while (recent.Count > RecentViewStateQueueMaxLength) // If we've got lots in the queue, remove the old ones 
    Cache.Remove(recent.Dequeue()); 
} 

そしてSessionPageStatePersisterを使用しての超簡単な方法のために、もう一度mypage.aspx.csでこれを置く:

protected override PageStatePersister PageStatePersister 
{ 
    get 
    { 
     return new SessionPageStatePersister(this); 
    } 
} 
+1

5年後、このコードはまだ価値のあるコピーパスタです。私はこれをVB.NETコンバータに入れて、わずかなマイナーな編集の後に私のページに貼り付けることができました。私は決してサーバーメモリにviewstateを格納することをお勧めしたいと思いますが、AngularとWebAPIを使用する15年前のWebFormsアプリケーションを書き直すと、これは一時的な解決策としてはうまく機能します。キャッシュされたviewstateが期限切れになるのを待つのではなく、完了したらそれをクリーンアップしてください。 – oscilatingcretin

+0

@scilatingcretinしたがって、LoadPageStateFromPersistenceMedium()でビューステートを返す直前に、Cache.Remove(viewStateKey)を実行しますか?私はそれ以降のコールバックのために新しいviewstateが生成されるので、そこで行うのは安全ですか? SavePageStateToPersistenceMedium()内の古いものをクリアするのはまだ良い考えです。 – Radderz

+0

私の最後の提案を無視してください。ロード後は削除できません。ユーザーが同じフォームデータをポストバックするページを更新した場合はどうなりますか?それはそのページの状態を失うでしょう。 – Radderz

関連する問題