TOC
Caching:

OutputCache

In ASP.NET WebForms, as well as in ASP.NET MVC versions before the Core framework, the concept of OutputCache existed. It made it extremely easy to cache entire pages/views, just like we saw with ResponseCache in the previous article, but stored in memory on the webserver.

The concept of OutputCache hasn't made it into the Core version of the .NET framework, as of writing this, but fortunately for us, the community has developed a version, based on in-memory caching, which gives you the same opportunties as the OutputCache features that was built into previous versions. In fact, there are likely several implementations out there, but I will base this article on the WebEssentials.AspNetCore.OutputCaching NuGet package.

As soon as you have installed this package in your project, you just need to make a couple of small adjustments in your Startup.cs file, to start using the OutputCache directive:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
services.AddOutputCaching();    
services.AddMvc();    
    }
   
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.UseOutputCaching();    
app.UseMvcWithDefaultRoute();
    }
}

The "magic" happens in the call to services.AddOutputCaching() and app.UseOutputCaching(). Now your website supports output caching and you can start using it like this:

[OutputCache(Duration = 120)]
public IActionResult Index()
{    
...

Now, your page is cached in the memory of the webserver for 120 seconds and will only be generated on the first request (and then again when the cache has expired). If you want to verify this, you can either start debugging the project after setting a breakpoint inside the action/method, or you can pass in a DateTime instance and then output it in the View like this:

Controller:

[OutputCache(Duration = 120)]
public IActionResult Index()
{    
    return View(DateTime.Now);
}

View:

@model DateTime

Time of request: @Model.ToString()

Try requesting the page and notice that the date and time remains the same, even when reloading the page, until the cache has expired.

OutputCache Options

We already used a very important option when using the OutputCache: The Duration. It will tell the framework how long it can rely on the cached version, before it needs to be refreshed. There are several other relevant options though:

VaryByParam

Without any further options than the Duration, the request will be cached no matter what and served to all other users, but in many situations, your page might change depending on how the user accesses it. For instance, you might use parameters in the query string to serve different content based on how the user requests it, like this:

/Users/Details?id=1
/Users/Details?id=2
....

In a situation like that, you want the caching to take the parameter of the name "id" into consideration when caching the content. This is easily accomplished by using the VaryByParam option:

[OutputCache(Duration = 120, VaryByParam = "id")]
public IActionResult Details(int id)
{
    return View(id);
}

Multiple versions of the Details View can now exist in the cache, depending on which value was passed to the id parameter. You can specify multiple parameter names, like this:

[OutputCache(Duration = 120, VaryByParam = "id,page,time")]
public IActionResult Details(int id)
{
...

VaryByHeader

You can also vary the content based on headers sent to the server from the client, e.g. "User-Agent", which identifies a client (a webbrowser). It can be used like this:

[OutputCache(Duration = 120, VaryByHeader = "User-Agent")]
public IActionResult Index()
{    
    return View(DateTime.Now);
}

This will vary the content based on which browser is used, and there are of course many other types of headers that you can use - for inspiration, have a look at this list of HTTP header fields.

Summary

Thanks to the OutputCaching NuGet package, you can have the same type of OutputCache functionality as previously found in ASP.NET WebForms and earlier versions of the MVC framework.