Integrate Angular and ASP.NET Core Web-Api into Microsoft IIS

TRAN Ngoc Thach
6 min readOct 9, 2019

Introduction

It makes sense that different technologies are usually employed for different use-cases. There is increasingly no “one-size-fit-all” in tech-sphere. It doesn’t mean to downplay the importance of “all-in-one” solutions as the latter typically promises high-level integration between components, resulting in higher efficiency and reducing time-to-market.

In my case, I needed a website, consisting of Frontend and Backend.

System Design

Regarding Frontend, Angular became an immediate choice because it is well-known, actively maintained by Google. A quick google search, given the right keyword, can lead us to the right solution instantly for an Angular problem. Developing Frontend with Angular is a joyful experience, thanks to its readily available/free Web Components. After compiling, it ends up as static files! Undoubtedly, serving static files in Web Server is extremely fast.

Regarding Backend, it is expected to be an Api-Server. .NET Framework was chosen due to it maturity. With .NET Core Framework, one can even deploy on Linux with either Nginx or Apache. The website’s main functionality is data transformation/manipulation; as a result, functional programming is preferable. Given such constraints, Microsoft F# is the optimal choice. Creating a Web-Api project with ASP.NET Core for F# can’t be easier.

Everything is all set! The very next step after developing is to deploy it somewhere so that end-users have a chance to play with the website and give valuable feedbacks. Although Nginx/Apache can be used as Web Server, we focus on Microsoft IIS in this article.

Searching around the Internet, there were many approaches in integrating Angular/ASP.NET Core Web-Api into IIS. One of them is to treat the Frontend’s (compiled) static files as static files within ASP.NET Core. In my case, I completely decoupled the Frontend and Backend for easier maintenance (no chance of interfering with each other).

Integration

Below are the steps to build and integrate Angular (Frontend) and ASP.NET Core Web-Api (Backend) into IIS.

Build the Frontend

Separation between Frontend and Backend means they exist on their own projects. It is often the case that in Frontend code (Angular), we use HttpClient to communicate with Backend (Web-Api) via a prefix-address, e.g. http://localhost:5000/api. An example of Restful API call: http://localhost:5000/api/user/check/1 to get information about User with ID 1. Due Frontend and Backend being hosted in one place (IIS), it is not needed to specify an independent address for Backend; that said, replace http://localhost:5000/apiwith /api.

Next, in Command Prompt, move to the Frontend’s project folder, type:

ng build --prod --base-href /
Build Frontend (Angular)

The compiled files will be stored in distfolder.

Double checking, in the resultant index.html, one must see this tag:

<base href="/">

Build the Backend

Before compiling, a few more line of codes are added to facilitate the integration of ASP.NET Core Web-Api into IIS:

// Program.fs
module Program =
let exitCode = 0

let BuildWebHost args =
WebHost
.CreateDefaultBuilder(args)
.UseKestrel() // important!
.UseIISIntegration() // important!
.UseStartup<Startup>()
.Build()

[<EntryPoint>]
let main args =...
// Startup.fs
type Startup private () =
...
member this.ConfigureServices(services: IServiceCollection) =
...
services.AddAuthentication(IISDefaults.AuthenticationScheme) |> ignore
member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) =
...
app.UseAuthentication() |> ignore

Kestrel is used in place of HttpSys for IIS integration, which can be further explained here.

Since .NET Core v2.2 , Microsoft introduces In-Process IIS integration. In my case, we still used .NET Core v2.1; thus, Out-Of-Process IIS integration was the only option. The strong advantage of former option is performance.

In Command Prompt, move to the Backend’s project folder, type:

dotnet publish -c Release -r win10-x64

If using a different Windows version, e.g. Windows 8.1, check here for the right Windows RID. win10-x64targets Windows 10/Server 2016 x64.

The compiled files will be stored in \bin\Release\netcoreapp2.1\win10-x64\publish folder.

Install some prerequisites for Microsoft IIS

In my case, only authenticated users are allowed to access the website, thanks to Active Directory. To enable this feature, a few things in the Server (Windows Server 2016) must be installed beforehand.

Windows Authentication

In order to host an ASP.NET Core application within IIS, the .NET Core Runtime must be available. In this website, choose the right version for “ASP.NET Core/.NET Core: Runtime & Hosting Bundle”. The latest Patch version for the Runtime is prefered as it has the latest Security Patch. The Server should be rebooted after this installation.

Thanks to link, check if the ASP.NET Core Runtime for Windows Server Hosting has been installed properly:

Integrate Frontend (Angular) into IIS

Copy content of the dist folder to somewhere, e.g. C:\Website\FE. Then, in IIS, add a website:

Add Website

In the Wizard, configure as followed:

Add Website Wizard

After that, in IIS, enable Windows Authentication within the website:

Enable Windows Authentiction

Integrate Backend (ASP.NET Core Web-Api) into IIS

Copy content of the publishfolder to somewhere, e.g. C:\Website\BE. Then create an unmanaged pool for hosting the ASP.NET Core application.

Add Application Pool
Application Pool with No Managed Code

The next step is to add an Application to this website. One may wonder the difference between a Website and an Application within IIS’ terminologies, see here. Notice that we must choose the right Application Pool in the Wizard ( NoManagedCodeAppPool) as well as the right alias api.

Add Application
Add Application Wizard

When IIS receives an API call, e.g. GET http://myserverdomain.com/api/user/check/1, it will divert the traffic to the Application api. Inside this Application (Web-Api), the controller UserControlleris fetched and its method check() with input parameter 1 is called. Therefore, in Web-Api code, a Controller should look like this:

// UserController.fs
[<Route("[controller]")>]
type UserController () =
inherit Controller()
[<HttpGet("check/{userId:int}")>]
member this.Check([<FromRoute>] userId: int64): ObjectResult =

Last but not least, restart the Website:

Conclusion

In this article, we have learned to integrate Frontend (Angular) and Backend (ASP.NET Core Web-Api) into Microsoft IIS with Active Directory support.

In my opinion, Angular and ASP.NET Core Web-Api is a good combination for quickly building decent websites. .NET Core is a feature-rich/cross-platform framework, enabling us to do all kinds of things in the Backend. Angular provides a great abstract layer over raw HTML/Javascript (Component-based architecture) and diverse sets of Web Controls, all of which boosts the productivity in developing Frontend.

Tested version: Windows Server 2016 Standard x64, IIS v10, Angular 5, ASP.NET Core v2.1.

--

--