If you’ve been working with ASP.NET Web Forms, you might be familiar with ViewState — a feature that automatically remembers control values between requests.
When you move to ASP.NET MVC, things change. MVC follows the stateless nature of HTTP, which means each request is independent. The framework doesn’t automatically preserve data between requests — you must manage state explicitly.
In this post, we’ll look at what “state management” means in MVC and the various techniques available to handle it.
What is State?
Simply put, state is the information that persists between user requests.
Examples:
- A user’s login status
- Items in a shopping cart
- Form data temporarily stored between pages
Because HTTP is stateless, every request starts fresh unless we implement some way to persist state ourselves.
State Management Types
There are two main categories of state management:
- Client-Side State Management – data is stored on the user’s browser.
- Server-Side State Management – data is stored on the server.
Let’s look at both in the context of MVC.
1. Client-Side State Management
a) Hidden Fields
Hidden fields allow you to store small amounts of data in HTML that are not visible to the user but sent back to the server on form submission.
@using (Html.BeginForm("Submit", "Home"))
{
@Html.Hidden("UserId", "123")
<input type="submit" value="Submit" />
}
When the form is posted, you can access it in your controller:
[HttpPost]
public ActionResult Submit(string userId)
{
// userId will be "123"
return View();
}
Pros:
- Easy to implement.
- No server resources required.
Cons:
- Data can be seen or modified in the browser (should not store sensitive info).
b) Query Strings
You can pass data between requests using the URL itself.
public ActionResult Index()
{
return RedirectToAction("Details", new { id = 5 });
}
URL: /Home/Details/5
Pros:
- Simple and transparent.
Cons:
- Limited length.
- Visible in the URL.
- Not suitable for sensitive data.
c) Cookies
Cookies store data on the client’s browser that persists across multiple requests or even sessions.
// Set a cookie
HttpCookie cookie = new HttpCookie("username", "John");
Response.Cookies.Add(cookie);
// Read a cookie
string user = Request.Cookies["username"]?.Value;
Pros:
- Persistent.
- Works across requests.
Cons:
- Limited size (~4KB).
- Users can disable cookies.
- Must be used carefully for privacy reasons.
2. Server-Side State Management
a) TempData
TempData is useful for passing data between two consecutive requests — for example, when you redirect after a POST.
public ActionResult Save()
{
TempData["Message"] = "Data saved successfully!";
return RedirectToAction("Index");
}
public ActionResult Index()
{
ViewBag.Message = TempData["Message"];
return View();
}
Key Point: TempData uses Session internally and is cleared after it’s read once.
b) Session
The Session object stores user data on the server. Each user has their own session identified by a unique session ID (usually stored in a cookie).
// Store
Session["UserName"] = "John";
// Retrieve
string name = Session["UserName"] as string;
Pros:
- Data is not exposed to the client.
- Easy to use.
Cons:
- Consumes server memory.
- Not suitable for large-scale distributed systems unless configured with a session store (like SQL Server or Redis).
c) Application State
This is global data shared by all users.
HttpContext.Application["TotalUsers"] = 100;
Pros:
- Useful for global counters or cached data.
Cons:
- Shared among all users — changes by one user affect others.