Single page applications (SPA) have become a standard in the web development world by now, reshaping the way web applications are designed. Traditionally a web browser (client) would send out a GET request to a server and the server would return an HTML page. Nowadays we have SPAs that rely on web APIs for data retrieval and that run like real applications in a browser. That’s why in the .Net ecosystem having .Net Core web APIs with Angular 2+ front end is a common scenario and it might be useful to look into different basic deployment strategies. Before I go any further, I want to point out that this article is aimed for junior developers, developers that are new to the .Net ecosystem or for all those that are on their way to become software developers.
Taking into consideration that nowadays a lot of applications are cloud hosted, we also need to think about scalability, performance and cost optimization. And that’s why there are two basic deployment strategies
- Deploy both the back end and front end together
- Deploy back end and front end separately
Why a separate deployment?
Well because in this scenario you split the load and can scale resources independently. Maybe your application in generating a lot of traffic on the front end while the back end is fairly quiet. Having these components deployed separately you can easily scale up resources for the front end component, while you scale down resources for the back end component. This is mostly of great benefit if you deploy your application to Azure AppService or similar cloud services from other providers, but is still of great value even if you host it on your own.
So let’s dive a little bit deeper in the two mentioned strategies.
Deploy .Net Core and Angular together
The concept here is very easy. When you build an Angular application, all needed script bundles, artifacts and index.html are created in the “dist” folder of your Angular project. You can simply change the destination of your build output to the wwwroot folder of your ASP .Net Core project. You can specify this in your .angular-cli.json file and the result would look something like this:
[code language=”javascript” highlight=”2″]
“root”: “src”,
“outDir”: “..YourNetCoreProject/wwwroot”,
“assets”: [
“assets”,
“favicon.ico”
],
[/code]
That’s easy, but there are many caveats that you need to be aware of. First of all let’s clarify that ASP.NET Core uses Kestrel as own webserver. So if you simply put your Angular generated files in the wwwroot folder Kestrel won’t know by default how to serve this files. Moreover, when a refresh is performed in the Angular application, a Get request will be sent to Kestrel, probably containing also a certain route (like http://myapp.com/users) that is unknown for the web server so Kestrel would by default throw a “not found exception”. So, in order to make your Angular front end work properly in the wwwroot, there are some configurations that need to be done in Startup.cs:
[code language=”csharp” highlight=”7, 8, 9, 10, 11, 12, 13″]
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = “/index.html”;
await next();
}
});
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
}
}
[/code]
The highlighted code is very important in this regard. This piece of middleware checks the requested path (e.g http://myapp.com/users) and if it is unknown to Kestrel, then it will serve the index.html together with the initially requested path. So Angular will be able to process and resolve it to an Angular route. Also, in order to serve the index.html file in this configuration, we need also the DefaultFiles middleware. Also, please note that middleware order is very important in ASP .Net Core so make sure that app.Use() comes before app.UseDeatultFiles().
Please note, this is not the only way make Angular work in symphony with ASP .NetCore. For instance, you could to serve the Angular files directly from the /dist folder (the folder where Angular puts build artifacts by default) and add a service in ConfigureServices() to serve the files from there:
[code language=”csharp”]
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = “ClientApp/dist”;
});
[/code]
And for the development environment you can configure a middleware that runs an npm script:
[code language=”csharp”]
app.UseSpa(spa =></div>
{
spa.Options.SourcePath = “ClientApp”;</div>
if (env.IsDevelopment())</div>
{
spa.UseAngularCliServer(npmScript: “start”);
}
});
[/code]
There are also third party NuGet packages that you can install and configure the way Angular files are served and how routes are resolved. I really can’t say exactly what’s the best way, but I certainly prefer the first option since it handles everything without third party libraries and keeps a clear separation between Angular and ASP.NET Core.
If everything is configured properly, you should be able to build bothe Angular and .Net Core projects and deploy them wherever you want.
Deploy .Net Core and angular separately
I’ve spent a lot of words on the first scenario, but this one will be short. Not because I don’t want to go into details anymore, but because this scenario is really straight forward. You build the .Net Core project and the Angular project and deploy them to different locations. Still, in this scenario you will mostly need to make sure that you Enable and configure CORS in ASP.NET core so that the Angular front end is able to perform API calls without any problems. Browsers will mostly respect your CORS configuration.
So that’s mostly it. I hope that this article will be helpful for those who struggle to find a proper tutorial on how to deploy a .NET Core back end with Angular front end. I was in this position one year ago and I know your struggles 🙂 If you find it useful, please spread the word and let your friends and network know about this article. Comments are also welcome! Cheers!
How useful was this post?
Click on a star to rate it!
Average rating / 5. Vote count:
Dan Patrascu-Baba
Latest posts by Dan Patrascu-Baba (see all)
- Configuration and environments in ASP.NET Core - 25/11/2019
- GraphQL in the .NET ecosystem - 19/11/2019
- A common use case of delegating handlers in ASP.NET API - 12/11/2019
About deploying .Net Core and angular separately, how do you build the two components?
For the Angular CLI, do you run \ClientApp\ng build?
For the .NET Core, do you run “dotnet publish” and if so where? from the root folder of the application or at \ClientApp?
How to do deploy the two separate components in IIS?