100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET Framework

ViewState Explained

How ASP.NET Web Forms' ViewState mechanism preserves control state across postbacks, how it's serialized, and when to disable it for performance.

Web Forms FoundationsIntermediate10 min readJul 10, 2026
Analogies

ViewState Explained

ViewState is the mechanism ASP.NET Web Forms uses to preserve a page's control values across postbacks despite HTTP being fundamentally stateless. After a control's properties change during processing, the page serializes those changes into a base64-encoded string and embeds it in a hidden field named __VIEWSTATE inside the rendered <form>; on the next postback, ASP.NET reads that field back and restores each control's state before Page_Load runs, which is how, for example, a Label's text set in code-behind survives a subsequent postback without you re-setting it manually.

🏏

Cricket analogy: ViewState is like a scorer carrying forward the exact match state — score, overs bowled, wickets — from the tea break to the resumption of play, rather than restarting the innings count from zero when play resumes.

How ViewState Works Under the Hood

Each control that participates in ViewState stores its tracked property changes in a StateBag, a dictionary-like structure, and the Page's SavePageStateToPersistenceMedium method (invoked around SaveStateComplete) walks the entire control tree, aggregates each control's StateBag via SaveViewState, and serializes the result — historically using the LosFormatter, an optimized binary serializer — before base64-encoding it into the __VIEWSTATE field. On the following request, LoadViewState reverses the process: the string is decoded, deserialized, and each control's StateBag is repopulated before its LoadViewState method restores individual properties, all of which happens before Page_Load fires.

🏏

Cricket analogy: Each control's StateBag is like an individual player's personal stats sheet, and aggregating them all into __VIEWSTATE is like compiling every player's sheet into the official match scorecard at the end of the innings.

Enabling, Disabling, and Sizing ViewState

The EnableViewState property, settable at both the page and individual control level, controls whether that scope participates in ViewState at all; setting it to false on a read-only Label or a large GridView that never needs to remember its state across a postback can substantially reduce the size of the rendered page, since __VIEWSTATE for a data-heavy grid can easily balloon to tens of kilobytes of base64 text sent with every single response. The trade-off is real: too little ViewState and controls lose their state unexpectedly after a postback, too much and every page load and postback pays a bandwidth and serialization tax, so tuning EnableViewState selectively on non-interactive display controls is a standard Web Forms performance technique.

🏏

Cricket analogy: Deciding what to keep in ViewState is like deciding which stats a scoreboard operator actively tracks live versus which historical records are archived separately, tracking too much live data slows the whole broadcast down.

ViewState vs Other State Mechanisms

ViewState is scoped to a single page and a single user, round-tripped through the client on every request, which distinguishes it from Session state (server-side, per-user, persists across multiple pages until it expires or the session ends), Cookies (client-side, can persist across visits entirely), and ControlState (a smaller, always-on subset of state a control author can mark as essential, immune to EnableViewState being turned off, used for things like a GridView's current page index). Choosing the right mechanism matters: putting a large object into Session bloats server memory across all users, while relying on ViewState for data that must survive across different pages simply won't work, since ViewState never leaves the current page.

🏏

Cricket analogy: ViewState is like notes scribbled on today's scorecard alone, valid only for this match; Session is like a player's full season stats tracked by the team across many matches; Cookies are like a fan's loyalty membership card that persists across seasons.

aspx
<%-- Disabling ViewState on a read-only, non-interactive control --%>
<asp:Label ID="StaticFooterLabel" runat="server" EnableViewState="false"
    Text="© 2026 Acme Corp." />

<%-- A GridView that never needs to remember state across postbacks --%>
<asp:GridView ID="ReportGrid" runat="server" EnableViewState="false"
    AutoGenerateColumns="true" />

ViewState is base64-encoded, not encrypted, so anyone can decode __VIEWSTATE and read its contents in a tool like the ViewState decoder. Worse, without a Machine Authentication Code (enabled by default via the EnableViewStateMac page/machine setting), a malicious client could tamper with the encoded values before submitting them back, potentially manipulating hidden business logic. Never rely on ViewState alone to protect sensitive or security-critical data, and always leave EnableViewStateMac enabled.

  • ViewState persists control state across postbacks via the base64-encoded __VIEWSTATE hidden field.
  • Each control's changed properties live in a StateBag, aggregated into __VIEWSTATE on SaveStateComplete.
  • LoadViewState restores control state before Page_Load fires on the following postback.
  • EnableViewState can be toggled at the page or control level to reduce page size for non-interactive controls.
  • ControlState is a smaller, always-on subset of state that remains active even if EnableViewState is false.
  • ViewState is page-and-user scoped, unlike Session (server-side, multi-page) or Cookies (client-side, multi-visit).
  • ViewState is only base64-encoded, not encrypted, so EnableViewStateMac must stay enabled to prevent tampering.

Practice what you learned

Was this page helpful?

Topics covered

#NETFramework#ClassicASPNETWebFormsWebPagesStudyNotes#MicrosoftTechnologies#ViewStateExplained#ViewState#Explained#Works#Under#StudyNotes#SkillVeris