Integrate Angular and ASP.NET Core Web-Api into Microsoft IIS
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/api
with /api
.
Next, in Command Prompt, move to the Frontend’s project folder, type:
ng build --prod --base-href /
The compiled files will be stored in dist
folder.
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-x64
targets 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.
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:
In the Wizard, configure as followed:
After that, in IIS, enable Windows Authentication within the website:
Integrate Backend (ASP.NET Core Web-Api) into IIS
Copy content of the publish
folder to somewhere, e.g. C:\Website\BE
. Then create an unmanaged pool for hosting the ASP.NET Core application.
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
.
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 UserController
is 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.