63

I need to see the contents of the viewstate of an asp.net page. I looked for a viewstate decoder, found Fridz Onion's ViewState Decoder but it asks for the url of a page to get its viewstate. Since my viewstate is formed after a postback and comes as a result of an operation in an update panel, I cannot provide a url. I need to copy & paste the viewstate string and see what's inside. Is there a tool or a website exist that can help viewing the contents of viewstate?

Serhat Ozgel
  • 23,496
  • 29
  • 102
  • 138
  • Isn't it just a base 64 encoded version of the serialized data? – mercutio Aug 22 '08 at 16:44
  • 2
    Very Late, but curious if this helps `string str = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(txtViewState.Text));` – Shubh Apr 30 '15 at 10:59
  • 1
    Make sure your ViewState is set as [not encrypted](https://msdn.microsoft.com/en-us/library/aa479501.aspx), otherwise none of these tools(answers) with work. – David Rogers Mar 22 '17 at 20:59
  • 2
    Add this to the web.config: `` to disable ViewState encryption per @David Rogers comment. – Hans Vonn Aug 02 '18 at 20:50

11 Answers11

43

Here's an online ViewState decoder:

http://ignatu.co.uk/ViewStateDecoder.aspx

Edit: Unfortunatey, the above link is dead - here's another ViewState decoder (from the comments):

http://viewstatedecoder.azurewebsites.net/

zb226
  • 9,586
  • 6
  • 49
  • 79
James
  • 2,404
  • 2
  • 28
  • 33
40

Use Fiddler and grab the view state in the response and paste it into the bottom left text box then decode.

Darren Kopp
  • 76,581
  • 9
  • 79
  • 93
  • 7
    I'm guessing something has changed - the textbox at the bottom left is a command prompt of some kind, and pasting in viewstate does nothing useful. I can't see where this has gone - is it still in the current version? – Ian Griffiths Jun 26 '12 at 21:59
  • 14
    For those using the current version of Fiddler (2.5.1), the text box described in this answer can now be found by clicking the TextWizard option in the menu along the top (*or* Tools > TextWizard *or* Ctrl+E). Paste the ViewState into the top box then change the Transform to "From Base64". – Chris Jul 30 '15 at 16:19
15

Here is the source code for a ViewState visualizer from Scott Mitchell's article on ViewState (25 pages)

using System;
using System.Collections;
using System.Text;
using System.IO;
using System.Web.UI;


namespace ViewStateArticle.ExtendedPageClasses
{
    /// <summary>
    /// Parses the view state, constructing a viaully-accessible object graph.
    /// </summary>
    public class ViewStateParser
    {
        // private member variables
        private TextWriter tw;
        private string indentString = "   ";

        #region Constructor
        /// <summary>
        /// Creates a new ViewStateParser instance, specifying the TextWriter to emit the output to.
        /// </summary>
        public ViewStateParser(TextWriter writer)
        {
            tw = writer;
        }
        #endregion

        #region Methods
        #region ParseViewStateGraph Methods
        /// <summary>
        /// Emits a readable version of the view state to the TextWriter passed into the object's constructor.
        /// </summary>
        /// <param name="viewState">The view state object to start parsing at.</param>
        public virtual void ParseViewStateGraph(object viewState)
        {
            ParseViewStateGraph(viewState, 0, string.Empty);    
        }

        /// <summary>
        /// Emits a readable version of the view state to the TextWriter passed into the object's constructor.
        /// </summary>
        /// <param name="viewStateAsString">A base-64 encoded representation of the view state to parse.</param>
        public virtual void ParseViewStateGraph(string viewStateAsString)
        {
            // First, deserialize the string into a Triplet
            LosFormatter los = new LosFormatter();
            object viewState = los.Deserialize(viewStateAsString);

            ParseViewStateGraph(viewState, 0, string.Empty);    
        }

        /// <summary>
        /// Recursively parses the view state.
        /// </summary>
        /// <param name="node">The current view state node.</param>
        /// <param name="depth">The "depth" of the view state tree.</param>
        /// <param name="label">A label to display in the emitted output next to the current node.</param>
        protected virtual void ParseViewStateGraph(object node, int depth, string label)
        {
            tw.Write(System.Environment.NewLine);

            if (node == null)
            {
                tw.Write(String.Concat(Indent(depth), label, "NODE IS NULL"));
            } 
            else if (node is Triplet)
            {
                tw.Write(String.Concat(Indent(depth), label, "TRIPLET"));
                ParseViewStateGraph(((Triplet) node).First, depth+1, "First: ");
                ParseViewStateGraph(((Triplet) node).Second, depth+1, "Second: ");
                ParseViewStateGraph(((Triplet) node).Third, depth+1, "Third: ");
            }
            else if (node is Pair)
            {
                tw.Write(String.Concat(Indent(depth), label, "PAIR"));
                ParseViewStateGraph(((Pair) node).First, depth+1, "First: ");
                ParseViewStateGraph(((Pair) node).Second, depth+1, "Second: ");
            }
            else if (node is ArrayList)
            {
                tw.Write(String.Concat(Indent(depth), label, "ARRAYLIST"));

                // display array values
                for (int i = 0; i < ((ArrayList) node).Count; i++)
                    ParseViewStateGraph(((ArrayList) node)[i], depth+1, String.Format("({0}) ", i));
            }
            else if (node.GetType().IsArray)
            {
                tw.Write(String.Concat(Indent(depth), label, "ARRAY "));
                tw.Write(String.Concat("(", node.GetType().ToString(), ")"));
                IEnumerator e = ((Array) node).GetEnumerator();
                int count = 0;
                while (e.MoveNext())
                    ParseViewStateGraph(e.Current, depth+1, String.Format("({0}) ", count++));
            }
            else if (node.GetType().IsPrimitive || node is string)
            {
                tw.Write(String.Concat(Indent(depth), label));
                tw.Write(node.ToString() + " (" + node.GetType().ToString() + ")");
            }
            else
            {
                tw.Write(String.Concat(Indent(depth), label, "OTHER - "));
                tw.Write(node.GetType().ToString());
            }
        }
        #endregion

        /// <summary>
        /// Returns a string containing the <see cref="IndentString"/> property value a specified number of times.
        /// </summary>
        /// <param name="depth">The number of times to repeat the <see cref="IndentString"/> property.</param>
        /// <returns>A string containing the <see cref="IndentString"/> property value a specified number of times.</returns>
        protected virtual string Indent(int depth)
        {
            StringBuilder sb = new StringBuilder(IndentString.Length * depth);
            for (int i = 0; i < depth; i++)
                sb.Append(IndentString);

            return sb.ToString();
        }
        #endregion

        #region Properties
        /// <summary>
        /// Specifies the indentation to use for each level when displaying the object graph.
        /// </summary>
        /// <value>A string value; the default is three blank spaces.</value>
        public string IndentString
        {
            get
            {
                return indentString;
            }
            set
            {
                indentString = value;
            }
        }
        #endregion
    }
}

And here's a simple page to read the viewstate from a textbox and graph it using the above code

private void btnParse_Click(object sender, System.EventArgs e)
        {
            // parse the viewState
            StringWriter writer = new StringWriter();
            ViewStateParser p = new ViewStateParser(writer);

            p.ParseViewStateGraph(txtViewState.Text);
            ltlViewState.Text = writer.ToString();
        }
Sameer Alibhai
  • 3,092
  • 4
  • 36
  • 36
  • code worked for me, but I did have to add a reference to one of the assemblies actually involved in producing the view state – Maslow Jan 16 '15 at 16:32
  • You need to include a reference to "System.Web" in your project if you paste this into a console application. Otherwise it will not build... – David Rogers Mar 22 '17 at 17:26
6

JavaScript-ViewState-Parser:

The parser should work with most non-encrypted ViewStates. It doesn’t handle the serialization format used by .NET version 1 because that version is sorely outdated and therefore too unlikely to be encountered in any real situation.

http://deadliestwebattacks.com/2011/05/29/javascript-viewstate-parser/


Parsing .NET ViewState


XP1
  • 6,910
  • 8
  • 54
  • 61
  • 1
    This one worked for me in Firefox even when other viewstate parsers did not. The links to the article are appreciated too. – Doug Domeny Oct 08 '13 at 19:57
6

As another person just mentioned, it's a base64 encoded string. In the past, I've used this website to decode it:

http://www.motobit.com/util/base64-decoder-encoder.asp

Josh Hinman
  • 6,745
  • 7
  • 38
  • 47
  • 5
    It's a base64 encoded serialised object, so the decoded data is not particularly useful. It's best to use a proper View State decoder. – James Feb 12 '11 at 11:23
  • 1
    With other decoders, I keep getting decoding errors. This has been the first way that actually works for me. Granted, it's just a straight string decoding rather than a viewstate decoder, but it gets me much further down the road than anything else so far. +1 Many Thanks!! – Richard Jun 15 '12 at 13:11
6

Here's another decoder that works well as of 2014: http://viewstatedecoder.azurewebsites.net/

This worked on an input on which the Ignatu decoder failed with "The serialized data is invalid" (although it leaves the BinaryFormatter-serialized data undecoded, showing only its length).

Roman Starkov
  • 59,298
  • 38
  • 251
  • 324
3

This is somewhat "native" .NET way of converting ViewState from string into StateBag Code is below:

public static StateBag LoadViewState(string viewState)
    {
        System.Web.UI.Page converterPage = new System.Web.UI.Page();
        HiddenFieldPageStatePersister persister = new HiddenFieldPageStatePersister(new Page());
        Type utilClass = typeof(System.Web.UI.BaseParser).Assembly.GetType("System.Web.UI.Util");
        if (utilClass != null && persister != null)
        {
            MethodInfo method = utilClass.GetMethod("DeserializeWithAssert", BindingFlags.NonPublic | BindingFlags.Static);
            if (method != null)
            {
                PropertyInfo formatterProperty = persister.GetType().GetProperty("StateFormatter", BindingFlags.NonPublic | BindingFlags.Instance);
                if (formatterProperty != null)
                {
                    IStateFormatter formatter = (IStateFormatter)formatterProperty.GetValue(persister, null);
                    if (formatter != null)
                    {
                        FieldInfo pageField = formatter.GetType().GetField("_page", BindingFlags.NonPublic | BindingFlags.Instance);
                        if (pageField != null)
                        {
                            pageField.SetValue(formatter, null);
                            try
                            {
                                Pair pair = (Pair)method.Invoke(null, new object[] { formatter, viewState });
                                if (pair != null)
                                {
                                    MethodInfo loadViewState = converterPage.GetType().GetMethod("LoadViewStateRecursive", BindingFlags.Instance | BindingFlags.NonPublic);
                                    if (loadViewState != null)
                                    {
                                        FieldInfo postback = converterPage.GetType().GetField("_isCrossPagePostBack", BindingFlags.NonPublic | BindingFlags.Instance);
                                        if (postback != null)
                                        {
                                            postback.SetValue(converterPage, true);
                                        }
                                        FieldInfo namevalue = converterPage.GetType().GetField("_requestValueCollection", BindingFlags.NonPublic | BindingFlags.Instance);
                                        if (namevalue != null)
                                        {
                                            namevalue.SetValue(converterPage, new NameValueCollection());
                                        }
                                        loadViewState.Invoke(converterPage, new object[] { ((Pair)((Pair)pair.First).Second) });
                                        FieldInfo viewStateField = typeof(Control).GetField("_viewState", BindingFlags.NonPublic | BindingFlags.Instance);
                                        if (viewStateField != null)
                                        {
                                            return (StateBag)viewStateField.GetValue(converterPage);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                if (ex != null)
                                {

                                }
                            }
                        }
                    }
                }
            }
        }
        return null;
    }
Basil
  • 51
  • 2
2

You can ignore the URL field and simply paste the viewstate into the Viewstate string box.

It does look like you have an old version; the serialisation methods changed in ASP.NET 2.0, so grab the 2.0 version

blowdart
  • 55,577
  • 12
  • 114
  • 149
2

Best way in python is use this link.

A small Python 3.5+ library for decoding ASP.NET viewstate.

First install that: pip install viewstate

>>> from viewstate import ViewState
>>> base64_encoded_viewstate = '/wEPBQVhYmNkZQ9nAgE='
>>> vs = ViewState(base64_encoded_viewstate)
>>> vs.decode()
('abcde', (True, 1))
henrry
  • 486
  • 6
  • 25
1

Online Viewstate Viewer made by Lachlan Keown:

http://lachlankeown.blogspot.com/2008/05/online-viewstate-viewer-decoder.html

XP1
  • 6,910
  • 8
  • 54
  • 61
  • 1
    While this may answer the question, [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Taryn Mar 10 '13 at 20:20
  • 1
    @bluefeet What else is there to add? The only essential part is the decoder itself. The other two answerers did the same thing and only posted the link. – XP1 Mar 11 '13 at 00:25
0

Normally, ViewState should be decryptable if you have the machine-key, right? After all, ASP.net needs to decrypt it, and that is certainly not a black box.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • 1
    of course, you are correct. I meant that if it's encrypted, you won't be able to decode it *easily* – Josh Hinman Aug 22 '08 at 17:19
  • 1
    Just in case anyone stumbles across this answer ... ViewState is never encrypted. It is merely base64 encoded. No key is needed. – Rap Jan 30 '14 at 23:12
  • 3
    @Rap In .NET 4.5 I cannot simply base64 decode it. There's more to it than that. Online tools simply return an empty string while ViewState decoders throw some sort of error. This leads to believe that even if it's not encrypted per se it _is_ encoded beyond just base64. – ahwm May 18 '15 at 15:59
  • 5
    @ahwm True story. .Net 4.5 is encrypting ViewState. That wasn't true when I wrote my comment 16 months ago, but it is now. You are correct. – Rap May 19 '15 at 18:02
  • 1
    @Rap Thanks for that clarification. That makes sense why it wouldn't work for me but there were posts and posts about how to decode it. Thought I was going crazy or that our in-house CMS was doing weird things. – ahwm May 19 '15 at 20:03