Do not rely on Client Side validations

Do not rely on client side validations.

When writing code for displaying information for some specific users, some developers usually bring to the HTML only what is really necessary.
If some user should not see some data, then the HTML can be already assembled without those tags.
Let’s say that the full info would be something like this:

<ul>
	<li>Name: John Smith</li>
	<li>E-mail: john@emaildomain.com</li>
	<li>Telephone: (555) 555-5555</li>
	<li>Address: 55 Dream Street, New York, NY</li>
</ul>

But if you are not a premium user you should only see the following information:

<ul>
	<li>Name: John Smith</li>
	<li>E-mail: john@emaildomain.com</li>
</ul>

One way of doing that could be returning the HTML from the back-end ready to be displayed.
Another way could be interacting through the HTML code – maybe an .aspx or .cshtml file if you are working with .NET (Web Forms or MVC), or even an .asp or .php file – by using an If statement.
(the following examples will be written with the Razor view engine)

<ul>
	<li>Name: John Smith</li>
	<li>E-mail: john@emaildomain.com</li>
	@(if (Model.IsPremiumUser))
	{
		<li>Telephone: (555) 555-5555</li>
		<li>Address: 55 Dream Street, New York, NY</li>
	}
</ul>

So far, no problems with this approach.
The problem starts when the developer trusts this dynamic HTML assembling enough to forget some basic validation principles.
This then starts to bring some development habits like enabling or disabling some input fields or buttons by inserting HTML attributes to tags, such as readonly or disabled, or by using javascript methods to do that.
Fair enough, just not safe enough.
Let’s take a look at a possible client side code:

(this code is simplified enough to allow developers from other technologies other than .NET to easily understand. It could surely use the HtmlHelpers for creating the fields and the form)

<form action="/Personal/Information" method="post">
	<input type="hidden" id="UserId">@Model.UserId</input>
	<b>Name: @Model.Name</b><br>
	E-mail: <input type="text" id="Email" readonly="true">@Model.Email</input>
	@(if (Model.IsPremiumUser))
	{
		Telephone: <input type="text" id="PhoneNumber">@Model.PhoneNumber</input>
		Address: <input type="text" id="Address">@Model.Address</input>
	}
	<button @(Model.CanSave ? "type='submit'" : "disabled='disabled'")>Update</button>
	<button class="delete" onclick="deleteRecord('@Model.UserId')">Delete Record</button>
</form>

<script>
	$(document).ready(function () {
		@if (!Model.CanDelete)
		{
		<text>
			$('.delete').hide();
		</text>
		}
	});

	function deleteRecord(userId)
	{
	// executes an Ajax post to delete the user's record
	}
</script>

Nice! Since the user is not a Premium User and do not have some permissions, the HTML is not displaying the Phone Number field nor the Address.
Also, it does not allow the user to change his or her e-mail address.
Furthermore, the user cannot click the Update button, first because it does nothing (it is just a button with no action) and it is also DISABLED!
We are safe too because the Delete button is HIDDEN! We did that with jQuery.

The final generated HTML, if you do not have permissions and are a non-premium user, would be:

<form action="/Personal/Information" method="post">
	<input type="hidden" id="UserId">5150ce6d3e11f80f18983829</input>
	<b>Name: John Smith</b><br>
	E-mail: <input type="text" id="Email" readonly="true">john@emaildomain.com</input>
	<button disabled="disabled">Update</button>
</form>

In the back-end, let’s say that there is a .NET MVC Controller waiting for that post, like this:

// This code is simplified for demonstration purposes
// It could vary a lot by using try/catch, not using repository, checking the ModelState, among many other things

[HttpPost]
public ActionResult Information(UserInformationViewModel model)
{
	if (UserDomain.Save(model.UserId, model.Email, model.PhoneNumber, model.Address))
		return RedirectToAction("Home");
	return View(model);
}

Let’s say that inside that Save method we have something just like this:

public bool Save(string userId, string email, string phoneNumber, string address)
{
	var user = GetUserById(userId);
	user.Email = email;
	if (!string.IsNullOrEmpty(phoneNumber))
		user.PhoneNumber = phoneNumber;

	if (!string.IsNullOrEmpty(address))
		user.Address = address;

	UserRepository.Save(user);
}

We only save the phone number and the address in case they are not empty, that is, only if they were sent from the Post method.
We now are sufficiently safe!

Are we?!

In the past, I mean years ago, we could try to “hack” a web page by creating a local HTML file with a form post pointing to a specific action of that website.

<form action="http://thewebsitedomain/Personal/Information" method="post">
...
</form>

Some websites did not verify the identity of the sender of that action and accepted you to use any data in the input fields of the form you created.
This would be a Cross-site request forgery (CSRF/XSRF) attack. However, many websites simply did not accept a request from a different Referer (a post from a page other than the ones in the same domain). You could and still can create anti forgery tokens to verify that the user who is posting the data is the same that got that HTML page from the server.

But we are talking here about you, a normal user of the website, posting data to the same server.
Nothing wrong with that.
But remember that we were allowing only some information to be posted, updated and deleted.

Nowadays you can simply modify an HTML directly in the browser using the Html Inspection on Google Chrome and Internet Explorer, or Firebug for Mozila Firefox, for example.

With that, you can easily modify that final HTML from this:

<form action="/Personal/Information" method="post">
	<input type="hidden" id="UserId">5150ce6d3e11f80f18983829</input>
	<b>Name: John Smith</b><br>
	E-mail: <input type="text" id="Email" readonly="true">john@emaildomain.com</input>
	<button disabled="disabled">Update</button>
</form>

to this:

<form action="/Personal/Information" method="post">
	<input type="hidden" id="UserId">5150ce6d3e11f80f18983829</input>
	<b>Name: John Smith</b><br>
	E-mail: <input type="text" id="Email" readonly="true">john@emaildomain.com</input>
	<input type="text" id="PhoneNumber">444-444-4444</input>
	<input type="text" id="Address"></input>
	<button type="submit">Update</button>
	<button onclick="deleteRecord('5150ce6d3e11f80f18983829')">Delete Record</button>
</form>

You may be questioning how the user would know the IDs of the PhoneNumber and Address fields to add them manually into the HTML?
Well, honestly, we often use some very obvious names for the fields, so it is definitely not difficult to guess the IDs. The user can also find those properties when navigating through other pages of the website.
Also, notice that we modified the Update button to become a “submit” button and removed the “readonly” and the “disabled” attributes.
Also, we added the delete button manually now. Just by looking at the Javascript methods we could guess how exactly that would look like.

Now we are good enough to update the Phone Number, the Email address or even Delete that record!
Cool, huh?

Not for the developers that will have headache when that code goes to production.
Our validations in the server were not enough to avoid this problem, and we don’t want our application to have such dangerous security breach.
You may think that changing a phone number or an address is not a big deal. But imagine some important things like modifying a User Type to become an admin, or modifying other users’ data!

The first thing to do in order to avoid that kind of issue is not relying only on client side validations.
Whatever you do, always do Server Side validations as well.

On Saving, instead of only verifying if the PhoneNumber and Address properties are empty in order to save them, we should verify if the user has the right permissions to do that:

public bool Save(string userId, string email, string phoneNumber, string address)
{
	var user = GetUserById(userId);
	user.Email = email;
	// this now ensures that this user is a Premium User before modifying those two fields
	if (user.IsPremiumUser)
	{
		if (!string.IsNullOrEmpty(phoneNumber))
			user.PhoneNumber = phoneNumber;

		if (!string.IsNullOrEmpty(address))
			user.Address = address;
	}

	UserRepository.Save(user);
}

The same validation should be performed on Deleting a record, like:

...
if (user.CanDelete)
{
	UserRepository.Delete(user);
}
...

Also, to avoid a user to be able to modify other users’ information, we could validate in the Controller method if the ID to be modified is the same as the User who is logged in.

[HttpPost]
public ActionResult Information(UserInformationViewModel model)
{
	if (CurrentLoggedUser.Id != model.UserId)
		return RedirectToAction("Home");

	if (UserDomain.Save(model.UserId, model.Email, model.PhoneNumber, model.Address))
		return RedirectToAction("Home");
	return View(model);
}

That way, if the user is trying to modify anyone else’s data, he or she will be redirected to the Home page.

You can improve the server validation much further than this.

However, this post is to make you aware of the problems that you can face by relying only on client side validations and attributes.
You can surely use them, and that is good.
But also do a good server validation too. There is always someone willing to bypass your client code.

Thiago Sindra

View State: friend or enemy?

The following article was written by me in 2008 and originally published in the Mundo.NET magazine in Portuguese. It describes the roles of View State in ASP .NET for Framework 2.0. Some changes were surely made after the framework 3.0, but the core subject keeps the same and it’s worth it to study and understand it. I hope you have a good reading.

Update: the Magazine was discontinued a few years ago.


Many times the knowledge that we acquire regarding a technology grows faster in the vertical way than in the horizontal way, i.e., it’s usually common to get quantity instead of quality. The result of that can be problematic some times, making us to use some techniques more frequently because they’re useful, but we don’t know when or how to better apply them. The use of the View State is very common and helpful, however it can lead our application to a bad performance if we misuse or misunderstand it. This article tries to help you understand what View State is and how to use it in order to achieve a better result.   Introduction The View State, as its name already says, allows the visualization of the state of a control. If you were an ASP 3.0 developer some time, you probably needed many times a way to store the data displayed on the screen, using from Sessions to fields hidden in the form. Many times the user took an action, like a button click or a change of the selected item of a combo box, and some times the data on the screen simply dissapeared. The ASP.NET developer some times doesn’t see this happening and might believe that everythings is working perfectly; however, when the info is missed after a PostBack for the first time, the problems begin to show up and the developer is brought to a new world where a universe of possibilities is introduced. Then he or she meets the famous View State and what its role is. He/She “doesn’t have” the same simple problems of persisting data between PostBacks anymore and then starts to abuse the View State, using it on everything without knowing what can happen if it’s used in the wrong way. Also, the list of errors that the developer thought that was complete starts back to grow with new errors, and when he/she looks for a solution on the internet he/she finds unanswered questions or a set of workarounds. Indeed the View State was created to persist, that is, to retain the state of a page and its controls between postbacks, and if we have judgement we can use it to persist our own data at anytime. This View State is stored in the HTML code of the page that the server returns to the client, in a hidden field called _VIEWSTATE. To see it you just need to view the source code of any of your .NET pages in your browser. Notice that the size of this field can vary significantly between one and another page, because this will depend on the ammount of controls, their contents and types. The content of this field and how it’s structured are subjects that will be discussed later in this article. What you need to know is that, at some point, the data and states of the page and its controls are stored, written in the hidden field and also loaded later. For this, you need to know a little about the LifeCycle of a .NET page and its controls. In the next topic we will have a short explanation about this. When you better understand the View State, you are able to achieve a better performance in your applicatinos and, of course, to avoid some headaches caused by unsolved issues. The View State and the Life Cycle For a better understanding of the View State it’s necessary to have some knowledge about the life cycle of a .NET page. I won’t talk about all but the most important stages of a life cycle that can help you understand how the View State works. When the client requests a page to the Web server, this one proccess the request moving through many stages of the page. It’s important to remember that the page is derived from the base control class  System.Web.UI.Control and each of its child controls also have the same stages and this process is performed recursively. We can highlight the following stages: Instantiation The class derived from Page is created automatically in this stage. This generated class is the translation of your page to the class programming language (usually C# or VB.NET) having a hierarchy of controls. Thus it contains the tree of controls since its root  (the own page) until the children of the children and so on. This class is located in temporary files under WINDOWS\Microsoft.NET\Framework\VERSION\Temporary ASP.NET Files. This way the hierarchy of controls doesn’t need to be created every time a page is requested, but only in the first visit. Initialization In the initialization stage (Init method) all controls of the hierarchy (created previously already) are initialized. The best time to add controls dynamically is now, because the View State was still not loaded, and if the control is added now you can avoid problems when the View State is loaded. Load View State It’s right in this stage that the View State of the controls is loaded. As I mentioned in the Initialization stage, if the control is not loaded previously, this can cause problems during this stage. Imagine you added a DropDownList dynamically during another control’s event. When the stages of the Life Cycle of a page finish, the View State will be saved and the content of your dynamic DropDownList will be stored in the tree of this View State. But when you perform a postback again, the View State’s tree will be read in this Load View State stage and the data of the controls will be loaded. However you won’t have added your DropDownList to the controls hierarchy and this can cause a conflict of types. You will have more details about this issue ahead. The Load View State stage will only happen after a postback of the page. Load PostBack Data Here is where the data informed by the user before the postback is loaded to its respective controls.  However this only happens for the controls that implement the interface IPostBackDataHandler. An example of control that implements this interface is the TextBox. This means that the Web server – when the user inserts a text in the TextBox and do a postback – will make the inserted text to be loaded again to the TextBox in this stage. It’s important to have in mind that this only occurs for the controls that implement this interface. A Label, for example, doesn’t have this implementation, so if you do any change to the text of a Label programmatically, you will have to store this in the View State to have it persisted. This is done automatically in the life cycle Save View State, which is explained next.   Load In this stage, the page and its controls are loaded. We usually insert the event handlers and make calls to our own methods here, since that’s when the page starts loading and at this point the controls have already been created as well as their states have been restored, in case a postback have been performed. Save View State This stage is reached only in the end of the page’s life cycle. I once again remember you that the fact I mentioned this right after the Load stage doesn’t mean that they are adjacent, because other stages of the cycle happen between these two. I mention here only some that you have to take into account to better comprehend the View State. In this stage, the View State is saved, that is, the page executes its method SaveViewState() and call this method recursively for each of its child controls. At this moment, the state that must be persisted between the postbacks is saved, what means that all values returned from each control are serialized and then concatenated into one only codified 64 base string. Render In the Render stage is when the server generates the HTML code to deliver to the client that made the request. At this point the View State that was previously saved is written to a hidden field like the one in the Block 1. Block 1 – Example of the hidden field of the View State after a page Render

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKMTQzNDU2NzgxN2QYAQUeX19Db250
cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFIWN0bDA
wJGJoY3IkdCRfJFRpdGxlQmFyU2VhcmNoVGV4dIyKXp
Yq4IglmlFW/JZDsJtaviUf" />

These are some of the stages of the life cycle of a page that I’d like to highlight for allowing us to discuss a little about the View State. When to use it or not We’ve seen in the Block 1 an example of the field _VIEWSTATE and the value stored in it. In this example, the string stored is not too large since it’s not a postback. After executing the whole life cycle of the page, the View State is stored for the first time, retaining the current state of the controls. The properties of the controls – like the text of a TextBox for example –, which were inserted declaratively (directly in the HTML code), were already constructed in the controls in the Instantiation stage, and assigned to the HTML returned to the client at the Render stage. Let’s say you have a form in your page with a TextBox and a button, according to the Block 2 and the Image 1, but, since your page was visited for the first time, the data were already inserted declaratively. Block 2 – Example of the HTML of a page containing a form with a TextBox and a button

    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="testTextBox" Text="TEST" runat="server"></asp:TextBox>
        <asp:Button ID="testButton" Text="PostBack" runat="server" />
    </div>
    </form>
Image 1. TextBox and button inside a form of the page.

Now, for example, you just fill the text of the TextBox in the page with “My Text” and then click the button, causing a postback. When a postback occurs in the page, the Load View State stage is processed and the previous state that was persisted is then loaded. Remember that the previous state was just a form that had been loaded with the data inserted declaratively; that includes the TextBox with the text “TEST”. Then the page processes the data that you filled to the form, performs some methods, moving again through all stages of the life cycle, and saves the View State again in the end. If during this postback you debug the page and insert a breakpoint at the page’s method OnInit, you will see that the data of the controls will be the same that were set declaratively: text “TEST” in the TextBox.  But if you set a breakpoint at the page’s method Load, you’ll notice that now the data of the controls are those filled by you in the form: text “My Text” in the TextBox. So far, so good, but we’re going to do another test.

The controls have a property called EnableViewState, responsible for enabling or disabling the use of the View State for the respective control. We will do like the Block 3, setting the property EnableViewState  for the TextBox to false and next we will process the page again, changing the TextBox’s text from “TEST” to “MyText” and clicking the PostBack button. Block 3 – View State of TextBox disabled

    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="testTextBox" Text="TEST" runat="server" EnableViewState="false"></asp:TextBox>
        <asp:Button ID="testButton" Text="PostBack" runat="server" />
    </div>
    </form>

What happened? For our surprise, nothing changed. Even with the TextBox’s View State disabled, the text “My Text” filled before the postback persisted after the button was clicked. But how is that possible if we don’t have the View State enabled for the TextBox and their methods LoadViewState and SaveViewState are not executed anymore? This happens because, as I mentioned previously in the Load PostBack Data stage of the page’s life cycle, the controls that implement the interface IPostBackDataHandler persist their content between the postbacks, allowing us to take, in the other side, the value that was filled before the postback. It’s in this stage that these contents are restored and assigned. The hidden field _VIEWSTATE itself also implements this interface; if not, how would we restore the value of this field after the postback? The property EnableViewState of the class System.Web.UI.Control is enabled by default. So you can think: “why do I need the View State if the text of the TextBox is persisted automatically?”. But the TextBox doesn’t have only the Text property. Let’s add dynamically to the TextBox the property Width, increasing its size to 500 pixels, like the Block 4. We’ll also set the property EnableViewState back to true. Block 4 – Adding the property Width to the TextBox dynamically

protected void Page_Load(object sender, EventArgs e)
{
   if (!IsPostBack)
   {
       ((TextBox)form1.FindControl("testTextBox")).Width = new Unit("500px");
   }
}

This code is executed only the first time the page is visited, when it’s still not a postback. The TextBox then has the size of 500px. After clicking the postback button, everything remains the same, because this property that was dynamically added was saved in the View State and was persisted. If you click the button again, the property will still remain the same, because it is loaded and saved in the View State at each postback. However, if at this time we disable the property EnableViewState again and load the page, you will see that, after clicking the button and causing the postback, the property will be lost and the TextBox will get back to its original size. So, the controls that have their properties assigned declaratively and are not modified dynamically don’t need to persist the View State. For example, let’s take a DropDownList declared in the HTML code of the aspx file. We then add to it the items “A”, “B” and “C”, according to the Block 5. Block 5 – DropDownList added declaratively

    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="testDropDownList" runat="server">
            <asp:ListItem>A</asp:ListItem>
            <asp:ListItem>B</asp:ListItem>
            <asp:ListItem>C</asp:ListItem>
        </asp:DropDownList>
        <asp:Button ID="testButton" Text="PostBack" runat="server" />
    </div>
    </form>

As we’ve seen before, once this DropDownList was added declaratively, the View State is not necessary to persist the data. When we load the page, select the item “B” and click the button, the postback will be performed. You will noticed that the items remain in the list and the item “B” remains selected. The items are still in the list because they were inserted declaratively and they are constructed in the Instantiation stage, and the item “B” remains selected because the Load PostBack Data stage. That means that if we disable the View State for this control, nothing will happen. However, let’s remove the items that were inserted in the HTML code declaratively and create them programmatically, executing a DataBind() inside the page method OnInit(), according to the Blocks 6 and 7. Block 6 – DropDownList added declaratively without List Items

    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="testDropDownList" runat="server">
        </asp:DropDownList>
        <asp:Button ID="testButton" Text="PostBack" runat="server" />
    </div>
    </form>

Block 7 – Items added dynamically to the DropDownList

protected override void OnInit(EventArgs e)
{
   if (!IsPostBack)
   {
         List<string> list = new List<string>();
         list.Add("D");
         list.Add("E");
         list.Add("F");
         ((DropDownList)form1.FindControl("testDropDownList")).DataSource = list;
         ((DropDownList)form1.FindControl("testDropDownList")).DataBind();
   }
   base.OnInit(e);
}

The items “D”, “E” and “F” are added to the DropDownList only the first time the page is visited. But even this way you can notice that, after we click the button, the items remain in the list, because they were saved in the View State. If we select the item “E” and click the button, it will still remain selected because the Load PostBack Data stage. But if we moved our code from the OnInit() to the Page_Load() method, we would lose the selection of the item, because the Page_Load() happens in the Load stage, that happens only after the Load PostBack Data. And this is the stage where the item selection is persisted. But let’s keep the code as it is now, in the OnInit() method. If we had disabled the View State of the DropDownList, we’d see that we would have lost all items of the list as soon as we performed a postback in the page, because our method adds the items to the DropDownList only the first time the page is visited. You’re probably questioning the reason for all these examples and this explanation until now. What happens is that we most times do a DataBind() every time a page is visited, and not only the first. This way, we wouldn’t have to save hundreds of items of a DropDownList to the View State since they are added dynamically every time the page is loaded, and we haven’t done any change. This is also true for a GridView, for example, that processes a DataBind() every time the page is loaded. This all might seem to not make any difference, but let’s firstly see what happens to the _VIEWSTATE field if we have 2 DropDownLists and 1 GridView in the page, each one having 20 items. But let’s disable the View State for these 3 controls. Check it out in the Block 8. Block 8 – Items of DropDownLists and GridView are not saved in the View State

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKLTY2MTMzNTgwNGQYAQUNdGVzdGVHcm
lkVmlldw9nZG61y7ld7A4nPSKwZhS9mOBP3KVP" />

Now we’ll see in the Image 2 what will happen if we let the View State enabled  unnecessarily  for these 3 controls.

Image 2. View State for the DropDownLists and the GridView.

The page size with the View State disabled for the 3 controls, according to the Block 8, is 8.31KB, while the page size with the View State enabled for the 3 controls, as shown in the Image 2, is 16.1KB, i.e., twice the size of the first. Here we just used 3 simple controls in the page, but can you imagine a page of a Web portal with several controls of this kind with the View State enabled by default for all of them and where many users have a bad internet connection? The page size can reach higher values and, each time a postback occurs, the user sends the request to the server with all fields of the form, including the _VIEWSTATE, and gets the rendered page from it. If the user does several postbacks, like sorting a GridView for example, these data are sent and received everytime, and that can reduce the performance. For this reason it’s quite good to know exactly when to use or not the View State. If we know this, we can also check if it’s better to use Session or View State at some cases, as we will learn next. Session vs. View State Maybe you have faced a situation when you didn’t know if you should use Session or ViewState to persist data between postbacks. Let’s check the differences between them to get some conclusion. Session already exists since the ASP andit’s stored in the server. For that, it uses the pair key-value, as shown in Block 9. The key is the identification to access the value, that is the content being stored. The Session, as it’s stored in the server, is persisted between different pages of the same application, and can store several object types. The drawback is that if you store complex objects and much data, and also have multi-user concurrency with simultaneous access, this can affect the memory of the server. You have to consider that the Session has a timeout, and you need to know what’s the best time to set in your application. Block 9 – Assiging a value to a Session

Session["key"] = value;

The View State was introduced in ASP.NET and it just persists the state of a single page. It also uses the pair key-value to be accessed, but it stores simple types (like strings, integers, etc.) and objects that can be serialized. Since View State is stored at the own client’s page, it does not expire, and that can also be a advantage depending on how it’s used. So, as we’ve seen before, it’s good to remember that, if you’re going to store lots of data, this can impact the page loading for certain connections. Block 10 – Assigning a value to the View State

ViewSate["key"] = value;

Therefore, both Session and View State can be used in the same page, just needing to identify the advantages of each one in each case.

In case your page is just an output with no postbacksand you don’t need to use View State, you can disable it with the following statement in the page:<%@ Page EnableViewState=”false” %>

Differences between ASP . NET 1.x and 2.0 As we’ve seen before, View State was introduced in ASP .NET 1.x and it brought some issues with it. Bringing into memory, View State is always enabled by default, and we consequently end up storing a bunch of unnecessary data. ASP .NET 1.x has the DataGrid, for example, and it stores also information about pagination, editing and sorting. As we’ve noticed, this might not be good if we don’t need these values to be persisted between postbacks. We just want the data to be populated and that they don’t have any sorting or pagination for example. Or we also maybe wish the DataGrid to allow pagination, editing or sorting and also to persist these data, but we’re always doing a DataBind() in the control every time the page is load. So we don’t need this content to be stored in View State. In ASP .NET 1.x it would be hard to separate both ideas, but in ASP .NET 2.0 this was solved by creating the Control State concept. The Control State is the division of the View State regarding to the state of controls only. The controls implement this property to make this distinction. While we keep the content in View State, we use Control State to keep the state referring to some properties. For example, while the GridView, an old successor of DataGrid, stores its list of items in the View State, it also stores in the Control State the information about pagination, sorting, etc.; in other words, separate the Control State to save behavioral information. The new TextBox and the DropDownLost also use Control State. Technically, the Control State is stored inside the hidden field _VIEWSTATE. However, if we disable the View State of a GridView, the Control State will keep being stored in the hidden field smoothly. You can, if desired, do an override of the methods LoadControlState() and SaveControlState(), responsible for loading and saving the Control State respectively. It’s important to distinguish the Control State, to store behavioral information, of the View State, responsible for storing content information or user interface state. Another advantage in ASP .NET 2.0 is the possibility of declarative DataSources. That means that we can declaratively configure a DataSource for a control in the HTML code. This way, the DataBind() is performed to a control automatically. Because of this, the ASP .NET 2.0 framework checks whether the View State is enabled or not for that page. If the View State is enabled, the DataBind() is performed to the controls only in the first page visit. If it’s disabled, the DataBind() is executed every time the page is loaded. This smart engine is implemented in the base class DataBoundControl, which is implemented by the controls CheckBoxList, AdRotator, DropDownList, ListBox, BulletedList, RadioButtonList, GridView, DetailsView and FormView. Behind the scenes The View State property is inside the class System.Web.UI.Control, so all ASP .NET server controls have it. Usually, when a property of one of these controls is read or written, it accesses the View State directly, as shown at Block 11. Block 11 – Text property of a CheckBox

public virtual string Text
{
    get
    {
        string str = (string) this.ViewState["Text"];
        if (str != null)
        {
            return str;
        }
        return string.Empty;
    }
    set
    {
        this.ViewState["Text"] = value;
    }
}

Using a tool like Reflector we can view the decompiled code and follow up what’s behind this property. It has the methods get and set reading and writing directly to the View State. This kind of access to the View State.for Web Controls properties is made for properties of simple types, i.e., scalar valued types, like string, integer, boolean, etc. The View State is type of System.Web.UI.StateBag, and it uses a System.Collections.Specialized.HybridDictionary behind. That means that it can be accessed with the pair key-value, as discussed before and as you can notice in the access of the property in the Block 11. You can do an override of the methods LoadPageStateFromPersistenceMedium() and SavePageStateToPersistenceMedium(object state) of a page. The former is responsible for deserializing and loading the View State; the latter, for serializing and saving the View State. Let’s see the decompiled code for these two methods in the Block 12. Block 12 – Method LoadPageStateFromPersistenceMedium()

protected internal virtual object LoadPageStateFromPersistenceMedium()
{
    PageStatePersister pageStatePersister = this.PageStatePersister;
    try
    {
        pageStatePersister.Load();
    }
    catch (HttpException exception)
    {
        if (this._pageFlags[8])
        {
            return null;
        }
        exception.WebEventCode = 0xbba;
        throw;
    }
    return new Pair(pageStatePersister.ControlState, pageStatePersister.ViewState);
}

This is the moment when the LoadViewState stage happens, where the View State is loaded in the hidden field and, then, it’s deserialized and returned to the page. The PageStatePersister transforms the View State hidden field of the HTML into its properties ControlState and ViewState already desirialized. After that, the method returns a Pair with these two properties. The Block 13 shows the reverse moment, where the View State is saved on the page. Block 13 – Method SavePageStateToPersistenceMedium(object state)

protected internal virtual void SavePageStateToPersistenceMedium(object state)
{
    PageStatePersister pageStatePersister = this.PageStatePersister;
    if (state is Pair)
    {
        Pair pair = (Pair) state;
        pageStatePersister.ControlState = pair.First;
        pageStatePersister.ViewState = pair.Second;
    }
    else
    {
        pageStatePersister.ViewState = state;
    }
    pageStatePersister.Save();
}

This method is invoked at the Save View State stage. After the page calls SaveViewState(), it – together with its child controls – returns its final state, that is an object of type Pair, and that’s passed to this method. The PageStatePersister here puts the first item of the Pair state inside its ControlState property, and puts the second item of the Pair state inside its property ViewState. When it executes its method Save(), it will have set the View State serialized and transformed into a string of base 64, ready to be inserted in the hidden field of the HTML code in the Render stage. Security By having access to the methods of loading and saving of the View State in details, it means that we can build a Parser that will show us the content of this View State. Then it’s possible to read the hidden field of the HTML code and build the View State Tree again. It might look like an advantage, but at the same time it can be dangerous. For this reason it’s not good to insert confidential date into the View State, like passwords or connection strings. Imagine also if a malicious user could modify the View State of your page to process it. He could modify data that are only of your aknowledgement and that only your server could generate. Let’s take as example a ranking page of gambling games, where the user takes an action and is ranked for this, and the points worth money. You can save in the View State the information about points on each action taken, and if the user can change the View State, he can modify the amount of points the he should earn when taking an action. This could give you some headache. A solution for this is that the System.Web.UI.LosFormatter, responsible for serializing the View State, has the possibility of using the MAC (Machine Authentication Check). What it does is to execute a hashing of the View State and saving the value at its end. This way, when a postback is performed, LosFormatter checks if the hash is still the same for the loaded View State. If it’s different, it was modified between the postbacks. You can choose the hashing algorythm to be used by the LosFormatter, specifying it in the machine.config file, on the validation attribute of the <machineKey> element. The default algorythm used is the SHA1, but you can switch it to MD5. By default, the MAC is enabled, but you can disable it on changing the EnableViewStateMac property of the page to false. But be careful if you do this, because you will open a security hole in your application. While the validationKey attribute of the machine.config file is used for hashing, the decryptionKey indicates the kind of  cryptography used on View State. The LosFormatter allows only 3DES (Triple DES), but once there is no confidential data on View State, there is no need to encrypt it. Compression We have also the possibility to compact the View State. The serialized View State is written in the hidden field _VIEWSTATE of the HTML code and, as we’ve seen, it can become extremely large. A hint that can be applied is doing an override in the methods LoadPageStateFromPersistenceMedium() and SavePageStateToPersistenceMedium(object state) of the Block 12 and 13, respectively. When doing this, we can use the LosFormatter to serialize the View State and compact the resulting string, saving the compressed View State, or do the opposite to load the View State, as in the Block 14. Block 14 – Loading and Saving of the compressed View State

protected override object LoadPageStateFromPersistenceMedium()
{
         PageStatePersister pageStatePersister = this.PageStatePersister;
         pageStatePersister.Load();

         LosFormatter formatter = new LosFormatter();
         Pair pair = (Pair)pageStatePersister.ViewState;
         string viewState = pair.Second.ToString();
         byte[] data = Convert.FromBase64String(viewState);
         byte[] uncompressedData = VSCompression.Decompress(data);
         string str = Convert.ToBase64String(uncompressedData);
         Pair returnedViewState = (Pair)formatter.Deserialize(str);
         return returnedViewState;
}

protected override void SavePageStateToPersistenceMedium(object state)
{
         if (state != null)
         {
                 LosFormatter formatter = new LosFormatter();
                 StringWriter writer = new StringWriter();
                 formatter.Serialize(writer, state);
                 string viewState = writer.ToString();
                 byte[] data = Convert.FromBase64String(viewState);
                 byte[] compressedData = VSCompression.Compress(data);
                 string str = Convert.ToBase64String(compressedData);
                 PageStatePersister pageStatePersister = this.PageStatePersister;
                 if (state is Pair)
                 {
                          Pair pair = (Pair)state;
                          pageStatePersister.ControlState = pair.First;
                          pageStatePersister.ViewState = new Pair(((Pair)pair.Second).First,
                                                         (object)str);
                 }
                 else
                 {
                          pageStatePersister.ViewState = state;
                 }
                 pageStatePersister.Save();

         }
}

We used in this example a customized class called VSCompression, that contains methods of data compression, and can use the class GZipStream of System.IO.Compression, responsible for compressing and decompressing streams. In the View State loading we used the PageStatePersister to obtain the View State’s HTML, the class VSCompression to decompress it and the LosFormatter to deserialize the View State. In the View State saving the opposite way is done, using the LosFormatter to serialize, the VSCompression to compress and the PageStatePersister to save the View State. Take a look at how the VSCompression class is built in the Block 15: Block 15 – Example of a View State compression

public class VSCompression
{
         public static byte[] Compress(byte[] data)
         {
                 MemoryStream ms = new MemoryStream();
                 GZipStream stream = new GZipStream(ms, CompressionMode.Compress);
                 stream.Write(data, 0, data.Length);
                 stream.Close();
                 return ms.ToArray();
         }

         public static byte[] Decompress(byte[] data)
         {
                 MemoryStream ms = new MemoryStream();
                 ms.Write(data, 0, data.Length);
                 ms.Position = 0;
                 GZipStream stream = new GZipStream(ms, CompressionMode.Decompress);
                 MemoryStream temp = new MemoryStream();
                 byte[] buffer = new byte[1024];
                 while (true)
                 {
                          int read = stream.Read(buffer, 0, buffer.Length);
                          if (read <= 0)
                                   break;
                          else
                                   temp.Write(buffer, 0, buffer.Length);
                 }
                 stream.Close();
                 return temp.ToArray();
         }
}

  Common issues In the Save View State stage we have the asse,mbling of the View State tree that is stored. This tree contains the state information of the page controls. The ASP .NET contains the controls tree and this View State tree, and it accesses the values of the View State through the indexes of the controls. If a control is added dynamically in the wrong place and time, it can cause some conflicts in the reading and writing of the state information of a control. See the Image 3 next:

Image 3. Label control added dynamically

In this image we can see 3 controls. Let’s assume that the first and the last controls, a Label(index 0) and a Button(index 2) respectively, were added declaratively, i.e., they’re always fixed in the HTML code. By the other hand, the Label with index 1 (Bike) was added dynamically inside the Page_Load() method of the Load stage. When the View State is saved, it will keep the 3 values (“Car”, “Bike” and “Send”) with their indexes. When we do a postback, the View State will be loaded before the Label control “Bike” is added dynamically, because the Load View State stage occurs before the Load stage, that is the stage where the dynamic control is being added. The result will be like the image 4:

Image 4. View State loaded wrongly

The Label with index 1 was added dynamically, like before. However, since the control was added only after the View State loading, when the View State was loaded the controls hierarchy only had 2 controls. The View State tree doesn’t persist the identification of each control, but it has only the indexes and the values of their properties. When the View State was loaded, the value for the index 1 (“Bike”) was assigned to the control with the index 1 of the controls tree, and at that moment the Label had not been added dynamically yet, and the Button was the control with index 1. Thus, the Button, as it also has the Text property, received the value “Bike”, that was the key Text of the index 1 of the View State tree. After that, the dynamic Label was added in the Load stage, but it was too late, because the View State was already loaded. And what about the value “Send”, that was the third index in the View State tree? Since there was no control with the index 3 in the controls tree, the engine just ignored it.

In this case, no exception was thrown, because the property Text of both the Label and the Button have the same type: string. But what if the control added dynamically was customized, and it had a property also called “Text”, but with another type different from string? In this case, you would get an InvalidCastException. Therefore, if, instead of having a Button added declaratively, you had a DropDownList, you’d get another error (Block 15): Block 15 – Error when loading the View State tree

Failed to load viewstate.  The control tree into which viewstate
is being loaded must match the control tree that was used to save
viewstate during the previous request.  For example, when adding
controls dynamically, the controls added during a post-back must
match the type and position of the controls added during the initial
request.

Though this error informs that the problem is the moment when the controls are added dynamically, it can be a bit confused, because we did the same in the last two examples, and we hadn’t got any error in the first one, and in the second one we got another error. This error occurred because the View State that was saved for our Label added dynamically has a different type from the expected by the DropDownList. The  LoadViewState(object savedState) method of the Label expects a savedState object with the type Pair, while the DropDownList expects an object with the type Triple. The most controls save their View State as a Pair, but if a Pair is not enough, a Triple is used, as for a ListControl, that stores also the states of its children. Since the View State of those controls are different, we got the error described above. Final considerations So, it is very important to know when you should use or not the View State, as well as the time to add dynamic controls to the page, avoiding many unknown problems, like a heavy page load. If the View State is used at any rate, you can get some headaches, for both security and performance issues. The View State can be our best friend, but it can become our biggest enemy. The most we get deep into a technology or technique, the easier we can see their advantages and drawbacks, improving the use of our applications. However, the View State must be used in a good sense and then be enjoyed in the best way ever.

Mundo .NET Magazine

Capa   It was just published the 7th edition of the Mundo.NET magazine. In this edition there is an article that I wrote, which calls “ViewState: amigo ou rival” (ViewState: friend or enemy).
  You can find at this article ways to handle ViewState, so that it can make your life easy.
  A lot of people use this resource without knowing the best way to do this, decreasing their systems performance.
  The current edition content can be seen on http://www.mundodotnet.com.br. The edition 6 of this same magazine has also an article about Regular Expressions, that my friend, Eduardo Dias, and I wrote.
  This magazine can be acquired in the magazine stores in Brazil, or by the internet, on its own website.

Thiago Sindra

kick it on DotNetKicks.com

Revista Mundo .NET

Capa    Acaba de ser lançada a edição 7 da revista Mundo.NET.
Nesta edição há um artigo o qual escrevi, que chama-se “ViewState: amigo ou rival”.
   Nele você encontra formas de lidar com o ViewState de modo que este facilite sua vida.
   Muitos utilizam este recurso sem saber a melhor forma de fazê-lo, prejudicando assim o desempenho de seu sistema.
   O conteúdo da edição atual pode ser visto no site: http://www.mundodotnet.com.br.
A edição 6 da mesma revista conta também com um artigo que escrevi juntamente com um amigo, Eduardo Dias, sobre Expressões Regulares.
   A revista pode ser adquirida nas bancas do Brasil ou pela internet, em seu respectivo website.

Thiago Sindra