You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			286 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="SessionViewState.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>                                                                
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| using System;
 | |
| using System.Collections;
 | |
| using System.Diagnostics;
 | |
| using System.ComponentModel;
 | |
| using System.Globalization;
 | |
| using System.IO;
 | |
| using System.Runtime.Serialization;
 | |
| using System.Text;
 | |
| using System.Web;
 | |
| using System.Web.SessionState;
 | |
| using System.Web.Util;
 | |
| using System.Web.UI;
 | |
| using System.Security.Permissions;
 | |
| 
 | |
| namespace System.Web.UI.MobileControls
 | |
| {
 | |
|     /*
 | |
|      * Session-based view state.
 | |
|      *
 | |
|      * When saving view state on the server as session data, some critical problems
 | |
|      * arise. The core issue behind most of these is how to handle the user 
 | |
|      * clicking the Back button. When the user does this, there is no corresponding
 | |
|      * notification to the server, and the client and server session state are thrown
 | |
|      * out of sync. 
 | |
|      *
 | |
|      * This class attempts to alleviate this by storing a small history of view states
 | |
|      * in session data. 
 | |
|      *
 | |
|      * To save session view state, construct a new object, set the ViewState and ActiveForm
 | |
|      * properties, and call Save. You'll get back a reference that contains the 
 | |
|      * state reference to write out.
 | |
|      *
 | |
|      * To load session view state, construct a new object, and call Load. The class will
 | |
|      * attempt to construct the view state from its history.
 | |
|      *
 | |
|      * Copyright (c) 2000 Microsoft Corporation
 | |
|      */
 | |
| 
 | |
|     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
 | |
|     internal class SessionViewState
 | |
|     {
 | |
|         private static readonly String ViewStateKey = "ViewState";
 | |
|         private Object _state;
 | |
| 
 | |
|         internal SessionViewState() {
 | |
|         }
 | |
| 
 | |
|         internal /*public*/ Object ViewState
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _state;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 _state = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal /*public*/ Pair Save(MobilePage page)
 | |
|         {
 | |
|             SessionViewStateHistory history = (SessionViewStateHistory)page.Session[ViewStateKey];
 | |
|             if (history == null)
 | |
|             {
 | |
|                 history = new SessionViewStateHistory(HttpContext.Current);
 | |
|                 page.Session[ViewStateKey] = history;
 | |
|             }
 | |
| 
 | |
|             SessionViewStateHistoryItem historyItem = new SessionViewStateHistoryItem();
 | |
|             SaveTo(historyItem);
 | |
|             #if TRACE
 | |
|             historyItem.Url = page.Request.FilePath;
 | |
|             #endif
 | |
|             return history.Push(historyItem);
 | |
|         }
 | |
| 
 | |
|         internal /*public*/ void Load(MobilePage page, Pair id)
 | |
|         {
 | |
|             _state = null;
 | |
| 
 | |
|             SessionViewStateHistory history = (SessionViewStateHistory)page.Session[ViewStateKey];
 | |
|             if (history != null)
 | |
|             {
 | |
|                 SessionViewStateHistoryItem historyItem = history.Find(id);
 | |
|                 if (historyItem != null)
 | |
|                 {
 | |
|                     LoadFrom(historyItem);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void SaveTo(SessionViewStateHistoryItem historyItem)
 | |
|         {
 | |
|             historyItem.ViewState = _state;
 | |
|         }
 | |
| 
 | |
|         private void LoadFrom(SessionViewStateHistoryItem historyItem)
 | |
|         {
 | |
|             _state = historyItem.ViewState;
 | |
|         }
 | |
| 
 | |
|         #if TRACE
 | |
|         internal /*public*/ void Dump(MobilePage page, out ArrayList arr)
 | |
|         {
 | |
|             SessionViewStateHistory history;
 | |
|             if ((page is IRequiresSessionState) && !(page is IReadOnlySessionState))
 | |
|             {
 | |
|                 history = (SessionViewStateHistory)page.Session[ViewStateKey];
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 history = null;
 | |
|             }
 | |
| 
 | |
|             if (history != null)
 | |
|             {
 | |
|                 history.Dump(out arr);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 arr = new ArrayList();
 | |
|             }
 | |
|         }
 | |
|         #endif
 | |
| 
 | |
|         [
 | |
|             Serializable
 | |
|         ]
 | |
|         private class SessionViewStateHistoryItem : ISerializable
 | |
|         {
 | |
|             #if TRACE
 | |
|             public String Url;
 | |
|             public String Id;
 | |
|             #endif
 | |
|             public Object ViewState;
 | |
| 
 | |
|             public SessionViewStateHistoryItem()
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             public SessionViewStateHistoryItem(SerializationInfo info, StreamingContext context)
 | |
|             {
 | |
|                 String s = (String)info.GetString("s");
 | |
|                 if (s.Length > 0)
 | |
|                 {
 | |
|                     ViewState = new LosFormatter().Deserialize(s);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     ViewState = null;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
 | |
|             void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
 | |
|             {
 | |
|                 if (ViewState != null)
 | |
|                 {
 | |
|                     StringWriter s = new StringWriter(CultureInfo.InvariantCulture);
 | |
|                     new LosFormatter().Serialize(s, ViewState);
 | |
|                     info.AddValue("s", s.ToString());
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     info.AddValue("s", String.Empty);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Session view state history. This is the history record kept in each session.
 | |
| 
 | |
|         [
 | |
|             Serializable
 | |
|         ]
 | |
|         private class SessionViewStateHistory
 | |
|         {
 | |
|             private int _historySize;
 | |
|             private SessionViewStateHistoryItem[] _history;
 | |
|             private int _currentHistoryIndex = 0;
 | |
|             private int _historyUsed = 0;
 | |
|             private DateTime _sessionUniqueID = DateTime.Now;
 | |
|             private int _currentHistoryID = 0;
 | |
| 
 | |
|             public SessionViewStateHistory(HttpContext context)
 | |
|             {
 | |
|                 _historySize = ControlsConfig.GetFromContext(context).SessionStateHistorySize;
 | |
|                 if (_historySize < 1)
 | |
|                 {
 | |
|                     throw new Exception(
 | |
|                         SR.GetString(SR.SessionViewState_InvalidSessionStateHistory));
 | |
|                 }
 | |
| 
 | |
|                 _history = new SessionViewStateHistoryItem[_historySize];
 | |
|             }
 | |
| 
 | |
|             public Pair Push(SessionViewStateHistoryItem item)
 | |
|             {
 | |
|                 Pair id = new Pair(_sessionUniqueID, _currentHistoryID);
 | |
|                 _currentHistoryID++;
 | |
| 
 | |
|                 _history[_currentHistoryIndex] = item;
 | |
|                 _currentHistoryIndex = (_currentHistoryIndex + 1) % _historySize;
 | |
|                 if (_historyUsed < _historySize)
 | |
|                 {
 | |
|                     _historyUsed++;
 | |
|                 }
 | |
| 
 | |
|                 #if TRACE
 | |
|                 item.Id = _currentHistoryID.ToString(CultureInfo.InvariantCulture);
 | |
|                 #endif
 | |
|                 
 | |
|                 return id;
 | |
|             }
 | |
| 
 | |
|             public SessionViewStateHistoryItem Find(Pair id)
 | |
|             {
 | |
|                 // First make sure that the page is from the current session.
 | |
|                 DateTime uniqueID = (DateTime) id.First;
 | |
|                 if (DateTime.Compare(uniqueID, _sessionUniqueID) != 0)
 | |
|                 {
 | |
|                     return null;
 | |
|                 }
 | |
| 
 | |
|                 // Now check if we actually still have it.
 | |
|                 int historyID = (int) id.Second;
 | |
|                 int distance = _currentHistoryID - historyID;
 | |
| 
 | |
|                 if (distance <= 0)
 | |
|                 {
 | |
|                     // Shouldn't happen, but this would be a forward jump.
 | |
|                     return null;
 | |
|                 }
 | |
|                 else if (distance > _historyUsed)
 | |
|                 {
 | |
|                     // Gone way back. Empty history, but return null.
 | |
|                     _historyUsed = 0;
 | |
|                     return null;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     int foundIndex = (_currentHistoryIndex + _historySize - distance) % 
 | |
|                                      _historySize;
 | |
|                     // Make the found item the top of the stack.
 | |
|                     _currentHistoryIndex = (foundIndex + 1) % _historySize;
 | |
|                     _currentHistoryID = historyID + 1;
 | |
|                     _historyUsed -= distance - 1;
 | |
|                     return _history[foundIndex];
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             #if TRACE
 | |
|             public void Dump(out ArrayList arr)
 | |
|             {
 | |
|                 arr = new ArrayList();
 | |
|                 int n = _currentHistoryIndex;
 | |
|                 for (int i = 0; i < _historyUsed; i++)
 | |
|                 {
 | |
|                     n = n - 1;
 | |
|                     if (n == -1)
 | |
|                     {
 | |
|                         n = _history.Length - 1;
 | |
|                     }
 | |
| 
 | |
|                     SessionViewStateHistoryItem item = _history[n];
 | |
|                     if (item != null)
 | |
|                     {
 | |
|                         arr.Add(String.Format(CultureInfo.InvariantCulture, "{0}({1})", item.Url, item.Id));
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         arr.Add("(null)");
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             #endif
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 |