Now that we've set everything up, it's time to take a look at where we're doing. The first thing we should do is to turn our task runner on:
gulpfile.js
file and select Task Runner Explorer.watch
active in background.
If things are working as they should, we will see something very close to the preceding image. That's pretty good. Before going further, let's check if our task runner and its plugins are also working as they should.
Back in Visual Studio, open the /Scripts/app/app.component.ts
file and change the <div>
content with the highlighted text as follows:
import {Component} from "@angular/core";
@Component({
selector: "opengamelist",
template: `<h1>OpenGameList</h1><div>...the best is yet to come!</div>`
})
export class AppComponent { }
After you're done, hit CTRL + S or Save, then move back to the browser and issue a page refresh by hitting F5 to see if the task runner did its job. If it did, you should see something like the following:
So far so good, we have just set up a working skeleton of what's about to come.
If you're not seeing this, and the page is still showing the Work in progress..., phrase, chances are that you have caching issues. This is quite a common issue, since our client code relies upon static files (such as index.html
) which are served by default with a set of cache-control
HTTP headers to ensure a proper client-side cache. This is usually great for production, but it can be quite annoying while our app is in the development stage. If we want to fix it, we need to change the default caching behavior for static files.
If we were developing an ASP.NET 4 web application, we could do that by adding some lines to our main application's web.config
file such as the following:
<caching enabled="false" /> <staticContent> <clientCache cacheControlMode="DisableCache" /> </staticContent> <httpProtocol> <customHeaders> <add name="Cache-Control" value="no-cache, no-store" /> <add name="Pragma" value="no-cache" /> <add name="Expires" value="-1" /> </customHeaders> </httpProtocol>
And that should be it.
However, that's not the case. The new ASP.NET Core's configuration system has been re-architected from scratch and is now quite different from the previous versions. The most important consequence of this is that XML configuration files such as web.config
, together with the whole System.Configuration
namespace, are not part of the new pattern and shouldn't be used anymore.
The new configuration model is based upon key/value settings that can be retrieved from a wide variety of sources, including, and mostly being, Json files. Once retrieved, they can be accessed within our code in a strongly-typed fashion. We can take a look at the new pattern by watching a couple of lines contained within the Startup
class constructor, which is contained in the Startup.cs
file (relevant lines are highlighted):
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); }
And also the appsettings.json
file they refer to:
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } } }
Now that we understand the basics, let's see how we can solve that caching issue by taking advantage of the new configuration model.
The first thing to do is to understand how we can modify the default HTTP headers for static files. As a matter of fact, we can do that by adding a custom set of options to the app.UseDefaultFiles()
method we added to the Startup
class earlier. In order to do that, open the Startup.cs
and change that part of code in the following way (new/modified lines are highlighted):
// Configure a rewrite rule to auto-lookup for standard default files such as index.html. app.UseDefaultFiles(); // Serve static files (html, css, js, images & more). See also the following URL: // https://docs.asp.net/en/latest/fundamentals/static-files.html for further reference. app.UseStaticFiles(new StaticFileOptions() { OnPrepareResponse = (context) => { // Disable caching for all static files. context.Context.Response.Headers["Cache-Control"] = "no-cache, no-store"; context.Context.Response.Headers["Pragma"] = "no-cache"; context.Context.Response.Headers["Expires"] = "-1"; } });
That wasn't hard at all. However, we're not done yet, now that we've learned how to change the default behavior, we just need to change these static values with some convenient references pointing to the appsettings.json
file.
To do that, we can add the following key/value section to the appsettings.json
file in the following way (new lines are highlighted):
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "StaticFiles": { "Headers": { "Cache-Control": "no-cache, no-store", "Pragma": "no-cache", "Expires": "-1" } } }
And then change the preceding Startup.cs
code accordingly (modified lines are highlighted):
// Configure a rewrite rule to auto-lookup for standard default files such as index.html. app.UseDefaultFiles(); // Serve static files (html, css, js, images & more). See also the following URL: // https://docs.asp.net/en/latest/fundamentals/static-files.html for further reference. app.UseStaticFiles(new StaticFileOptions() { OnPrepareResponse = (context) => { // Disable caching for all static files. context.Context.Response.Headers["Cache-Control"] = Configuration["StaticFiles:Headers:Cache-Control"]; context.Context.Response.Headers["Pragma"] = Configuration["StaticFiles:Headers:Pragma"]; context.Context.Response.Headers["Expires"] = Configuration["StaticFiles:Headers:Expires"]; } });
That's about it. Learning how to use this pattern is strongly advisable, as it's a great and effective way to properly configure our application's settings.