Create an Angular demo app with .NET Core backend separated folder structure, CORS
The goal is to create an Angular demo app with .NET Core backend in the following folder structure - from scratch. It is a recommended way to separate frontend and backend in different folders (unlike the VS Templates suggests it):
Suggestion from Visual Studio WebApi Template with Angular: https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/angular
rem .NET Core project in the root
<myApp>\...
rem Angular code in ClientApp folder within then backend folder
<myApp>\ClientApp\...
The following approach separates the projects much better and it is less confusing for new developers/team members:
rem .NET Core project in backend folder
<myApp>\backend\...
rem Angular code in frontend folder
<myApp>\frontend\...
Some basic understanding of
Install “Visual Studio 2019” from https://visualstudio.microsoft.com. The free “Community” edition is just fine.
c:\temp\myAngular9NetCore3App
dotnet new webapi -n MyBackend
Rename the new folder from “MyBackend” to “backend”.
In Visual Studio, load this project: c:\temp\myAngular9NetCore3App\backend\MyBackend.csproj
Configure the green arrow in the toolbar (use the small arrow on the right side of the button): choose “MyBackend” instead of “IIS Express”. Run the project (press F5).
Your Browser will spin up and shows this URL: https://localhost:5001/weatherforecast
What you see here is some random json data from the demo controller. (see Controllers\WeatherForecastController.cs
). Due to randomizing, every time you refresh the browser, you’ll get different data.
Install the Angular CLI from cmd:
rem -g: globally in c:\Users\<username>\AppData\Roaming\npm\node_modules\
npm install -g @angular/cli
Open a cmd in this folder c:\temp\myAngular9NetCore3App
Create new Angular app in cmd:
rem --routing true: add routing
rem --style scss: scss is a modern css preprocessor
rem -g: skip git
ng new MyFrontend --routing true --style scss -g
Rename the new folder “MyFrontend” to “frontend”.
Run the new Angular app from cmd:
rem set \frontend as the start folder
cd c:\temp\myAngular9NetCore3App\frontend
rem s or serve: compile and start a small webserver
rem -o or --open: open browser
ng s -o
Your Browser will spin up and shows URL: http://localhost:4200
What you see here is the Angular demo website.
Open cmd in c:\temp\myAngular9NetCore3App\frontend
. Enter “code .” to spin up VS Code in the right folder:
rem 'code .' starts VS Code and sets the current folder as work directory
cd c:\temp\myAngular9NetCore3App\frontend
code .
Press Control-C in cmd or close browser to stop the web app.
Edit \src\app\app.module.ts
: Add HttpClientModule:
...
import { HttpClientModule } from '@angular/common/http';
imports: [
...
HttpClientModule
],
Call the backend: add some imports to app.component.ts;
import { Component, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
And add a constructor to the class, which gets the HttpClient injected:
constructor(http: HttpClient) {
http.get<any[]>('https://localhost:5001/weatherforecast').subscribe(result => {
console.warn("weatherforecast", result);
}, error => console.error(error));
}
typescript
import { Component, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'MyFrontend';
constructor(http: HttpClient) {
http.get<any[]>('https://localhost:5001/weatherforecast').subscribe(result => {
console.warn("weatherforecast", result);
}, error => console.error(error));
}
}
If it is not already running, start .NET Core Backend by pressing F5 in Visual Studio.
Now start frontend project:
rem Go to the frontend folder
cd c:\temp\myAngular9NetCore3App\frontend
rem s: serve
rem o: open browser
rem This will spin up a web server and a browser on http://localhost:4200
ng s --o
Note: If you get an error “Port 4200 is already in use”, you have it already running in another cmd.
Open Debugger tools in your browser by pressing Shift-Control-I. Refresh the console output and pressing F5.
Now you’ll see a CORS error in the console output:
CORS is a web security feature: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Backend and Frontend are served on different locations (ports), therefore we need to allow this access.
In the Backend, add CORS Policy to ConfigureServices (Startup.cs):
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://localhost:4200"); // Frontend URL
});
});
services.AddControllers();
}
Use CORS Policy in Configure (Startup.cs):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins); // AFTER app.UseRouting();
...
}
For this demo, we don’t need more security. But for a real application and to keep your app secure, CORS has to be configured very thoroughly.
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://localhost:4200") // Frontend URL
.AllowAnyHeader() // allow any Header
.AllowAnyMethod(); // also allow PUT and POST and other methods
// .WithMethods("PUT", "GET"); allow PUT and GET only
});
If you can see the array, you just created your first business application in Angular 9 and .NET core 3.1. Congratulations! Please let me know on twitter @patrikbo"> @patrikbo. Thank you!
Swagger/OpenApi are tools which can create your Angular code to access the backend: check this https://github.com/boeschenstein/angular9-dotnetcore-openapi-swagger