You can dramatically improve the performance of your ASP.NET MVC application by taking advantage of the framework's built-in output caching mechanism. If you have a high-traffic page or an action that queries a large dataset from the database, output caching allows you to cache the HTML or JSON response directly in memory. By serving cached content for subsequent requests, you eliminate unnecessary database hits and drastically lower page load times.
In ASP.NET MVC 4 and 5, output caching can be implemented quickly using the standard [OutputCache] attribute without needing to build custom cache providers. Decorating your controller actions with this attribute gives you granular control over cache duration, location, and invalidation rules.
Default Caching Behavior in ASP.NET MVC
By default, GET actions in ASP.NET MVC return a Cache-Control header set to private. Consider a standard AJAX endpoint returning JSON:
If you inspect the response headers using Fiddler or Browser Developer Tools, you will see output similar to this:
Because Cache-Control is set to private, browsers (especially Internet Explorer) might cache these AJAX responses locally for the current user session. This can lead to stale data or unexpected application behavior when underlying data changes. Explicitly configuring output caching gives you predictability and control over client and server cache rules.
Enabling the [OutputCache] Attribute
To control caching explicitly, decorate your action method with the [OutputCache] attribute and specify a Duration (in seconds):
}
Inspecting the HTTP response headers now reveals updated cache directives:
Testing It in Visual Studio
Remove the
[OutputCache]attribute and place a breakpoint inside your action method.Launch your application and press F5 (Refresh) in your browser—the breakpoint hits on every request.
Add
[OutputCache(Duration = 60)]back to the action and refresh again.The breakpoint hits once for the initial request. Subsequent refreshes within the 60-second window serve cached content instantly without stepping into the controller action.
Handling Dynamic Content with VaryByParam
When an action returns different content based on query strings or route parameters, you must instruct the cache engine to store separate instances for each variation using VaryByParam.
VaryByParam = "none": Ignores all incoming parameters and serves the exact same cached payload to every user.VaryByParam = "*": Creates a unique cache entry for every unique combination of query parameters.Explicit Parameter List: Specify exact parameters separated by semicolons (e.g.,
VaryByParam = "accountId;page").
For example, when caching a paginated or sorted grid:
[OutputCache(Duration = 1, VaryByParam = "*")]
///code to get all accounts
}
VaryByParam = "*" guarantees that requests for ?accountId=1&page=2 and ?accountId=1&page=3 receive their corresponding cached views rather than returning the same cached data for both pages.