e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
144 lines
6.2 KiB
C#
144 lines
6.2 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="SessionPageStatePersister.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.Web.UI {
|
|
using System.Collections;
|
|
using System.Collections.Specialized;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Web.SessionState;
|
|
using System.Web.Configuration;
|
|
using System.Web.Security.Cryptography;
|
|
|
|
public class SessionPageStatePersister : PageStatePersister {
|
|
private const string _viewStateSessionKey = "__SESSIONVIEWSTATE";
|
|
private const string _viewStateQueueKey = "__VIEWSTATEQUEUE";
|
|
|
|
public SessionPageStatePersister(Page page) : base (page) {
|
|
HttpSessionState session = null;
|
|
try {
|
|
session = page.Session;
|
|
}
|
|
catch {
|
|
// ignore, throw if session is null.
|
|
}
|
|
if (session == null) {
|
|
throw new ArgumentException(SR.GetString(SR.SessionPageStatePersister_SessionMustBeEnabled));
|
|
}
|
|
}
|
|
|
|
public override void Load() {
|
|
NameValueCollection requestValueCollection = Page.RequestValueCollection;
|
|
if (requestValueCollection == null) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
string combinedSerializedStateString = Page.RequestViewStateString;
|
|
string persistedStateID = null;
|
|
bool controlStateInSession = false;
|
|
|
|
// SessionState will persist a Pair of <bool requiresControlStateInSession, string/pair>,
|
|
// where if requiresControlStateInSession is true, second will just be the sessionID, as
|
|
// we will store both control state and view state in session. Otherwise, we store just the
|
|
// view state in session and the pair will be <id, ControlState>
|
|
if (!String.IsNullOrEmpty(combinedSerializedStateString)) {
|
|
Pair combinedState = (Pair)Util.DeserializeWithAssert(StateFormatter2, combinedSerializedStateString, Purpose.WebForms_SessionPageStatePersister_ClientState);
|
|
// Check if we are storing control state in session as well
|
|
if ((bool)combinedState.First) {
|
|
// So the second is the persistedID
|
|
persistedStateID = (string)combinedState.Second;
|
|
controlStateInSession = true;
|
|
}
|
|
else {
|
|
// Second is <sessionID, ControlState>
|
|
Pair pair = (Pair)combinedState.Second;
|
|
persistedStateID = (string)pair.First;
|
|
ControlState = pair.Second;
|
|
}
|
|
}
|
|
|
|
if (persistedStateID != null) {
|
|
object sessionData = Page.Session[_viewStateSessionKey + persistedStateID];
|
|
if (controlStateInSession) {
|
|
Pair combinedState = sessionData as Pair;
|
|
if (combinedState != null) {
|
|
ViewState = combinedState.First;
|
|
ControlState = combinedState.Second;
|
|
}
|
|
}
|
|
else {
|
|
ViewState = sessionData;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
// Setup the formatter for this exception, to make sure this message shows up
|
|
// in an error page as opposed to the inner-most exception's message.
|
|
HttpException newException = new HttpException(SR.GetString(SR.Invalid_ControlState), e);
|
|
newException.SetFormatter(new UseLastUnhandledErrorFormatter(newException));
|
|
|
|
throw newException;
|
|
}
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// To be supplied.
|
|
/// </devdoc>
|
|
public override void Save() {
|
|
bool requiresControlStateInSession = false;
|
|
object clientData = null;
|
|
|
|
Triplet vsTrip = ViewState as Triplet;
|
|
// no session view state to store.
|
|
if ((ControlState != null) ||
|
|
((vsTrip == null || vsTrip.Second != null || vsTrip.Third != null) && ViewState != null)) {
|
|
HttpSessionState session = Page.Session;
|
|
|
|
string sessionViewStateID = Convert.ToString(DateTime.Now.Ticks, 16);
|
|
|
|
object state = null;
|
|
requiresControlStateInSession = Page.Request.Browser.RequiresControlStateInSession;
|
|
if (requiresControlStateInSession) {
|
|
// ClientState will just be sessionID
|
|
state = new Pair(ViewState, ControlState);
|
|
clientData = sessionViewStateID;
|
|
}
|
|
else {
|
|
// ClientState will be a <sessionID, ControlState>
|
|
state = ViewState;
|
|
clientData = new Pair(sessionViewStateID, ControlState);
|
|
}
|
|
|
|
string sessionKey = _viewStateSessionKey + sessionViewStateID;
|
|
session[sessionKey] = state;
|
|
|
|
Queue queue = session[_viewStateQueueKey] as Queue;
|
|
|
|
if (queue == null) {
|
|
queue = new Queue();
|
|
session[_viewStateQueueKey] = queue;
|
|
}
|
|
queue.Enqueue(sessionKey);
|
|
|
|
SessionPageStateSection cfg = RuntimeConfig.GetConfig(Page.Request.Context).SessionPageState;
|
|
int queueCount = queue.Count;
|
|
|
|
if (cfg != null && queueCount > cfg.HistorySize ||
|
|
cfg == null && queueCount > SessionPageStateSection.DefaultHistorySize) {
|
|
string oldSessionKey = (string)queue.Dequeue();
|
|
session.Remove(oldSessionKey);
|
|
}
|
|
}
|
|
|
|
if (clientData != null) {
|
|
Page.ClientState = Util.SerializeWithAssert(StateFormatter2, new Pair(requiresControlStateInSession, clientData), Purpose.WebForms_SessionPageStatePersister_ClientState);
|
|
}
|
|
}
|
|
}
|
|
}
|