ViewState is a mechanism that preserves control values across postbacks by storing them in a hidden __VIEWSTATE field.
When ASP.NET pages post back to the server, control values must be retained so the page can render correctly. That’s what ViewState does—it’s a built-in mechanism that serializes control state into a hidden <input> field called __VIEWSTATE so values persist across round trips.
Quick Fix Summary
Disable ViewState where it’s not needed—set EnableViewState="false" in the @Page directive or on individual controls. For large pages, reduce ViewState size by disabling it on data-bound controls or turning it off for the entire page.
What’s Happening
ViewState is a base64-encoded string stored in a hidden form field that travels between browser and server with every postback.
ViewState is a base64-encoded string stored in a hidden form field that travels between browser and server with every postback. It’s turned on by default, so even unused controls add payload to the page.
According to Microsoft Support, as of .NET 8 (2026), ViewState is still used in Web Forms pages but has been largely replaced by model binding and client-side state in ASP.NET Core MVC and Razor PagesMicrosoft Support.
Why does ViewState exist in the first place?
ViewState exists to maintain control values across postbacks without requiring server-side storage.
Stateless HTTP makes it tricky to preserve UI state between requests. ViewState solves this by serializing control data into a compact string that travels with each postback. (Honestly, this is one of those features that made Web Forms click for developers back in the day.) Without it, you’d have to manually repopulate every dropdown and textbox on every round trip—which gets old fast.
Step-by-Step Solution
Disable ViewState where it’s not needed to reduce page payload and improve performance.
Disable ViewState for the entire page
Add this directive at the top of your .aspx file:
<%@ Page EnableViewState="false" %>
That single line cuts the __VIEWSTATE field completely. Just remember—any controls that rely on it will need alternative state management.
Disable ViewState for a specific control
In the control’s markup or code-behind, set:
myGridView.EnableViewState = false;
This prevents the control’s state from being serialized into __VIEWSTATE. Great for read-only grids that get rebound on every postback.
Verify ViewState size
Inspect the hidden field in the rendered HTML. If the __VIEWSTATE value exceeds 10 KB, consider disabling ViewState for data-bound controls like GridView, FormView, or ListView.
Encrypt ViewState (optional)
To protect ViewState from tampering, enable MAC and encryption in web.config:
<system.web>
<pages viewStateEncryptionMode="Always" />
<machineKey validation="SHA1" validationKey="AutoGenerate,IsolateApps" />
</system.web>
Note: SHA1 is considered weak as of 2026; migrate to AES if required by compliance standards. (Security folks really don’t love SHA1 anymore.)
If This Didn’t Work
Switch to Control State for critical data that must persist even when ViewState is disabled.
Switch to Control State
For critical control data that must persist, use Control State instead of ViewState. Control State is not user-modifiable and survives ViewState being disabled. Register it in your control’s OnInit method:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override object SaveControlState()
{
return myCustomState;
}
protected override void LoadControlState(object savedState)
{
myCustomState = (string)savedState;
}
See Microsoft’s guide on Control State.
Use Session State or TempData
For data that spans multiple pages, store values in Session or TempData instead. These live on the server and don’t bloat the page payload. (Perfect for shopping carts or multi-step forms.)
Migrate to ASP.NET Core
If you’re still using Web Forms in 2026, consider upgrading to ASP.NET Core (Razor Pages or MVC), where ViewState is obsolete and state is managed via TempData, Session, or client-side storage. (Trust me, your future self will thank you.)
Prevention Tips
Disable ViewState by default during design and use monitoring to keep payloads small.
| Tip |
Action |
| Design phase |
Disable ViewState by default in new pages. Enable it only when necessary. |
| Template |
Use a master page with <%@ Page EnableViewState="false" %> as default, then override per page. |
| Data binding |
Disable ViewState on GridView, DetailsView, and FormView if you re-bind on every postback. |
| Validation |
Use browser dev tools (F12 → Network tab) to monitor __VIEWSTATE size. Aim for under 5 KB per page. |
| Security audit |
Run a security scan to detect unencrypted ViewState. Enforce encryption via web.config or middleware in ASP.NET Core. |
What’s the biggest ViewState performance killer?
Data-bound controls like GridView often generate massive ViewState payloads.
Those lovely editable grids with paging and sorting? They love to stuff every row’s state into ViewState. (And suddenly your 2 KB page balloons to 50 KB.) The fix: disable ViewState on the control and rebind it fresh on each postback. Your users—and your bandwidth bill—will notice the difference.
How can I check if ViewState is actually causing problems?
Inspect the __VIEWSTATE hidden field in your page’s HTML source.
Open your browser’s dev tools (F12), look at the form data, and check the size of that base64 blob. If it’s pushing 20 KB+, you’ve found your culprit. (Honestly, anything over 10 KB is worth investigating.)
Is ViewState secure?
ViewState can be tampered with unless properly encrypted and validated.
By default? Not secure at all. The data is just base64-encoded and easily decoded. That’s why you should enable encryption in web.config if you’re handling sensitive data. (And seriously, don’t store passwords or credit cards in ViewState—ever.)
What’s the future of ViewState?
ViewState is being phased out in favor of ASP.NET Core’s modern state management.
Microsoft’s pushing Razor Pages and MVC hard, where ViewState doesn’t even exist. (Good riddance, we say.) If you’re still maintaining Web Forms apps in 2026, start planning that migration—your future self will appreciate the cleaner architecture.
Can I completely remove ViewState from my project?
Yes—by migrating to ASP.NET Core or carefully disabling it everywhere.
Start with new projects: disable ViewState by default and only enable it when absolutely necessary. For existing apps, audit each page and control, then systematically turn it off. (It’s tedious work, but the performance gains are worth it.)
What’s a good ViewState size target?
Aim for under 5 KB per page for optimal performance.
Anything over 10 KB starts to slow down page loads noticeably. (And above 20 KB? You’re basically punishing mobile users.) Keep it lean, keep it fast.
How does ViewState compare to modern alternatives?
Modern approaches like TempData, Session, and client-side storage are generally more efficient.
ViewState sends data back and forth with every postback. TempData and Session keep it server-side. Client-side storage (localStorage, sessionStorage) avoids server round trips entirely. (Need we say more?) For new projects, these are almost always better choices.
What’s the easiest ViewState optimization?
Disable ViewState on data-bound controls that rebind on every postback.
That single change often cuts your __VIEWSTATE field by 80% or more. (Seriously—try it on a GridView and watch the size drop.) Start there before diving into more complex solutions.
Edited and fact-checked by the TechFactsHub editorial team.