// Project: Salient
// http://salient.codeplex.com
//
// Copyright 2010, Sky Sanders <sky at skysanders.net>
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://salient.codeplex.com/license
//
// Date: May 5 2010
#region
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Web.UI;
using System.Xml;
#endregion
namespace Salient.Web
{
///<summary>
/// A helper class that decodes, deserializes the '__ViewState' hidden field
/// of an ASP.Net in to an object and then XML serializes the object to provide
/// a navigable map of the view state and control state.
///</summary>
public class ViewStateParser
{
#region Fields
private readonly XmlDocument _controlState;
private readonly string _text;
private readonly object _value;
private readonly XmlDocument _viewState;
#endregion
#region Constructors
///<summary>
///</summary>
///<param name="fieldValue"></param>
public ViewStateParser(string fieldValue)
{
_text = fieldValue;
(_viewState = new XmlDocument())
.AppendChild(_viewState.CreateElement("viewstate"));
(_controlState = new XmlDocument())
.AppendChild(_controlState.CreateElement("controlstate"));
_value = new LosFormatter().Deserialize(_text);
XmlSerializeValue(_viewState, _controlState, _viewState.DocumentElement, _value);
}
#endregion
#region Properties
///<summary>
///</summary>
public XmlDocument ControlState
{
get { return _controlState; }
}
///<summary>
/// The unencoded __ViewState
///</summary>
public string Text
{
get { return _text; }
}
///<summary>
/// The ViewState object
///</summary>
public object Value
{
get { return _value; }
}
///<summary>
///
///</summary>
public XmlDocument ViewState
{
get { return _viewState; }
}
#endregion
#region Private Methods
private static void XmlSerializeValue(XmlDocument viewState, XmlDocument controlState, XmlNode parentNode, object value)
{
if (value != null)
{
string typename = value.GetType().Name;
if (typename == "HybridDictionary")
{
XmlElement childNode = controlState.CreateElement(typename);
HybridDictionary hybridDictionary = (HybridDictionary) value;
if (controlState.DocumentElement != null)
{
controlState.DocumentElement.AppendChild(childNode);
foreach (object item in hybridDictionary)
{
XmlSerializeValue(controlState, controlState, childNode, item);
}
}
}
else
{
XmlElement childNode = viewState.CreateElement(typename);
parentNode.AppendChild(childNode);
switch (typename)
{
case "Triplet":
Triplet triplet = (Triplet) value;
XmlSerializeValue(viewState, controlState, childNode, triplet.First);
XmlSerializeValue(viewState, controlState, childNode, triplet.Second);
XmlSerializeValue(viewState, controlState, childNode, triplet.Third);
break;
case "Pair":
Pair pair = (Pair) value;
XmlSerializeValue(viewState, controlState, childNode, pair.First);
XmlSerializeValue(viewState, controlState, childNode, pair.Second);
break;
case "ArrayList":
foreach (object item in (ArrayList) value)
{
XmlSerializeValue(viewState, controlState, childNode, item);
}
break;
case "Array":
foreach (object item in (Array) value)
{
XmlSerializeValue(viewState, controlState, childNode, item);
}
break;
case "DictionaryEntry":
DictionaryEntry dictionaryEntry = (DictionaryEntry) value;
XmlSerializeValue(viewState, controlState, childNode, dictionaryEntry.Key);
XmlSerializeValue(viewState, controlState, childNode, dictionaryEntry.Value);
break;
case "IndexedString":
childNode.InnerText = ((IndexedString) value).Value;
break;
default:
childNode.InnerText = value.ToString();
break;
}
}
}
}
#endregion
}
}