Sitemap
Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

ViewState vs Session vs Request.Form in ASP.NET: Understanding the Differences

7 min readAug 13, 2026

--

Press enter or click to view image in full size

If you have worked with classic ASP.NET Web Forms, you have probably encountered ViewState, Session, and Request.Form.

At first glance, they may seem interchangeable: all three can be used to store or retrieve values between parts of an ASP.NET application, but they are fundamentally different.

Understanding where the data is stored, how long it lives, how it moves between requests, and who can access it is essential for building reliable ASP.NET Web Forms applications.

In this article, we will explore the differences between these three mechanisms and, most importantly, understand when you should use each one.

The Short Version

Before going deeper, here is the simplest way to think about them:

Press enter or click to view image in full size

A useful mental model is:

ViewState = “Remember this page’s state.”
Session = “Remember something about this user.”
Request.Form = “Give me what the browser just sent.”

Let’s understand why.

1. ViewState

ViewState is one of the most characteristic features of ASP.NET Web Forms.

Its primary purpose is to preserve the state of controls between postbacks.

Consider a simple TextBox:

<asp:TextBox 
ID="txtName"
runat="server" />

The user type “Bruno” and clicks a button.

The browser sends a request back to the server.

ASP.NET needs a mechanism to reconstruct the page state. This is where ViewState becomes important.

You can also explicitly store values in ViewState:

ViewState["UserName"] = "Bruno";

and retrieve them later:

string name = ViewState["UserName"] as string;

Where is ViewState stored?

This is one of the most important concepts:

ViewState is stored on the client side, inside the page sent to the browser.

Typically, it is represented by hidden fields such as:

<input type="hidden" 
name="__VIEWSTATE"
value="..." />

ASP.NET serializes the ViewState information and sends it to the browser.

When the user performs a postback, the browser sends that information back to the server.

Therefore, the flow is approximately:

Server
↓
ASP.NET serializes ViewState
↓
HTML page
↓
Browser
↓
User performs postback
↓
__VIEWSTATE sent back
↓
Server

This is why ViewState can become quite large.

2. ViewState Is Page-Specific

Another important characteristic is its scope.

ViewState is associated with a particular page.

For example:

ViewState["CustomerId"] = 123;

This value can be retrieved during subsequent postbacks of that page.

However, ViewState is not intended to be a general-purpose storage mechanism between different pages.

If you navigate from PageA.aspx to PageB.aspx, you should not think of ViewState as a mechanism for carrying application data from one page to another.

This is one of the most common misconceptions.

3. Session

Now let’s talk about Session.

Session solves a completely different problem.

While ViewState is primarily concerned with page state, Session is concerned with user/session state.

For example:

Session["UserId"] = 123;
Session["UserName"] = "Bruno";

On another page:

int userId = (int)Session["UserId"];
string userName = Session["UserName"] as string;

The value is available because both requests belong to the same user’s session.

This makes Session extremely useful for information that needs to survive across multiple pages.

For example:

Login.aspx
↓
Dashboard.aspx
↓
Orders.aspx
↓
OrderDetails.aspx

You could store the authenticated user’s identifier in Session and access it throughout the application.

4. Where Is Session Stored?

This is where Session differs significantly from ViewState.

Session data is generally maintained on the server side, depending on the configured session-state mode.

For example:

Session["CustomerId"] = 456;

The browser does not normally receive the actual value 456 as part of the Session mechanism.

Instead, the browser typically maintains a session identifier, commonly through a cookie such as:

ASP.NET_SessionId

The server uses that identifier to associate subsequent requests with the correct session.

Conceptually:

Browser
│
│ ASP.NET_SessionId
↓
Server
│
└── Session data
├── CustomerId
├── UserName
└── Other values

This is why Session is much more appropriate than ViewState when information needs to be shared across multiple pages.

5. Request.Form

Now we arrive at something fundamentally different.

Request.Form is not really a storage mechanism.

It represents data submitted by the browser as part of the current HTTP request.

For example, suppose you have:

<form method="post">
<input type="text" name="UserName" />
<input type="text" name="Email" />
<button type="submit">
Send
</button>
</form>

When the user submits the form, the browser sends something conceptually similar to:

UserName=Bruno&Email=bruno@example.com

On the server, you can retrieve those values using:

string userName = Request.Form["UserName"];
string email = Request.Form["Email"];

The important word here is: Current request.

Once that request has finished, Request.Form is not a persistent storage mechanism.

6. Request.Form Does Not “Remember” Anything

Imagine this:

protected void btnNext_Click(object sender, EventArgs e)
{
string name = Request.Form["UserName"];
}

The value exists because the browser submitted it with that request.

If you make another request later, that value will only be available if the browser submits it again.

This is completely different from Session:

Session["UserName"] = "Bruno";

Session can preserve the value across multiple requests.

Request.Form cannot.

A simple way to visualize this is:

Request #1
↓
Request.Form["UserName"]
↓
"Bruno"
↓
Request finishes
↓
Request.Form is gone

7. The Three Mechanisms Side by Side

Let’s use a practical scenario.

Imagine a Web Forms application where a user selects a customer.

We could store the Customer ID in three different ways:

ViewState

ViewState["CustomerId"] = 123;

Best interpretation:

“I need this value while working with this page and its postbacks.”

Session

Session["CustomerId"] = 123;

Best interpretation:

“I need this value available to this user across multiple requests/pages.”

Request.Form

string customerId = Request.Form["CustomerId"];

Best interpretation:

“The browser just submitted this value to me.”

These three statements may look similar, but they represent three completely different concepts.

8. A Practical Example

Imagine we have two pages:

Customer.aspx
↓
Order.aspx

The user selects:

CustomerID = 123

and we need to send this information to Order.aspx.

Get Bruno Destro’s stories in your inbox

Join Medium for free to get updates from this writer.

One option is to use a form submission:

<form method="post" action="Order.aspx">
<input type="hidden"
name="CustomerId"
value="123" />
<button type="submit">
Continue
</button>
</form>

Then in Order.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
string customerId = Request.Form["CustomerId"];
}

This is a very explicit data transfer.

The browser sends the value, the destination page receives it.

No Session is required.

9. Request.Form vs QueryString

There is another mechanism that is frequently confused with Request.Form:

Request.QueryString.

For example:

Order.aspx?CustomerId=123

You can retrieve the value using:

string customerId = Request.QueryString["CustomerId"];

The difference is that QueryString data is sent in the URL.

Request.Form data is sent in the HTTP request body for a form POST.

Conceptually:

GET

Order.aspx?CustomerId=123
↑
QueryString

versus:

POST

CustomerId=123
↑
Request.Form

For sensitive information, neither should be treated as a security boundary by itself. Data sent by the client should always be validated on the server.

10. What About Security?

This is an extremely important distinction.

Because ViewState is sent to the browser, you should not treat it as a secure server-side storage mechanism.

Similarly, Request.Form contains data supplied by the client.

The client controls what is sent.

Therefore, never assume:

Request.Form["UserId"]

is trustworthy simply because your application generated the form.

A malicious client can potentially modify the request.

The same principle applies to client-controlled state in general:

Never trust client input. Validate it on the server.

Session is different because the actual session data is maintained by the server/session provider.

However, even Session data should not automatically be considered authorized merely because it exists. Authorization decisions should still be based on the application’s security model.

11. Performance Considerations

ViewState can have a significant impact on page size.

Imagine a page containing a large amount of ViewState:

HTML
├── Controls
├── CSS
├── JavaScript
└── __VIEWSTATE
└── Large serialized state

Every postback may send that ViewState back to the server.

Large ViewState can therefore increase:

  • Page size
  • Network traffic
  • Browser processing
  • Server processing
  • Postback latency

This is particularly important in large Web Forms applications.

If a value does not need to survive a postback, don’t put it into ViewState unnecessarily.

12. Session Has Its Own Risks

Session solves many problems, but that doesn’t mean you should put everything into it.

For example, storing huge objects in Session can increase server memory consumption.

Imagine:

Session["HugeData"] = someLargeObject;

If many users do this simultaneously, the application can consume significant amounts of memory.

Therefore, Session should contain small, meaningful pieces of user-specific state, rather than becoming a dumping ground for application data.

A good rule is:

Store only what you actually need.

13. What Should I Use?

Here’s the practical decision tree I use.

Use ViewState when:

  • The value belongs to the current Web Forms page.
  • You need it across postbacks.
  • The value represents page/control state.
  • You don’t need it on another page.

Example:

ViewState["SelectedTab"] = "Orders";

Use Session when:

  • The value belongs to the current user’s session.
  • Multiple pages need access to it.
  • The value must survive multiple requests.

Example:

Session["CustomerId"] = 123;

Use Request.Form when:

  • The browser is submitting data.
  • You need to receive values from a POST request.
  • You intentionally want to transfer data from one request/page to another.
  • You don’t need the value to persist automatically after the request.

Example:

string customerId = Request.Form["CustomerId"];

14. A Simple Mental Model

If you only remember one section of this article, remember this:

                  ASP.NET Web Forms
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
ViewState Session Request.Form
│ │ │
▼ ▼ ▼
Page state User state Request data
│ │ │
Postbacks Multiple pages Current request
│ │ │
Client-side Server-side Client → Server

Or even simpler:

ViewState
"I belong to this page."

Session
"I belong to this user."

Request.Form
"I was just sent by the browser."

15. Final Thoughts

ASP.NET Web Forms provides several mechanisms for maintaining and transferring state, and choosing the right one can make a significant difference in application architecture.

ViewState is primarily about preserving page state between postbacks.

Session is about maintaining user-specific state across multiple requests and pages.

Request.Form is about receiving data submitted by the client in the current HTTP request.

They are not interchangeable.

The biggest mistake is to think of them simply as different places to store variables.

They represent different layers of the HTTP/Web Forms lifecycle.

Once you understand that distinction, many Web Forms problems become much easier to reason about.

When you ask yourself “Where does this value belong?”, the answer usually becomes clear:

Does it belong to the page? → ViewState.

Does it belong to the user’s session? → Session.

Was it just submitted by the browser? → Request.Form.

And that simple distinction can save you from a lot of unnecessary complexity in ASP.NET Web Forms applications.

--

--