项目作者: boeschenstein

项目描述 :
Create an Angular demo app with .NET Core backend separated folder structure, CORS
高级语言: HTML
项目地址: git://github.com/boeschenstein/angular9-dotnetcore3.git
创建时间: 2020-04-11T11:24:02Z
项目社区:https://github.com/boeschenstein/angular9-dotnetcore3

开源协议:

下载


Angular 9 (Frontend) and .NET Core 3.1 (Backend)

Goal

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

  1. rem .NET Core project in the root
  2. <myApp>\...
  3. rem Angular code in ClientApp folder within then backend folder
  4. <myApp>\ClientApp\...

The following approach separates the projects much better and it is less confusing for new developers/team members:

  1. rem .NET Core project in backend folder
  2. <myApp>\backend\...
  3. rem Angular code in frontend folder
  4. <myApp>\frontend\...

Content

What you should bring

Some basic understanding of

  • Windows
  • .NET and C#
  • npm, node
  • Web technology

Create a new WebAPI project (backend)

Backend Preparation

Install “Visual Studio 2019” from https://visualstudio.microsoft.com. The free “Community” edition is just fine.

Create new .NET WebAPI project

  • Create a folder c:\temp\myAngular9NetCore3App
  • Start cmd in this folder
  • Now create a new webapi project in cmd:
  1. 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.

New Angular 9 project (frontend)

Frontend Preparation

Install the Angular CLI from cmd:

  1. rem -g: globally in c:\Users\<username>\AppData\Roaming\npm\node_modules\
  2. npm install -g @angular/cli

Create new Angular project

Open a cmd in this folder c:\temp\myAngular9NetCore3App

Create new Angular app in cmd:

  1. rem --routing true: add routing
  2. rem --style scss: scss is a modern css preprocessor
  3. rem -g: skip git
  4. ng new MyFrontend --routing true --style scss -g

Rename the new folder “MyFrontend” to “frontend”.

Run the new Angular app from cmd:

  1. rem set \frontend as the start folder
  2. cd c:\temp\myAngular9NetCore3App\frontend
  3. rem s or serve: compile and start a small webserver
  4. rem -o or --open: open browser
  5. ng s -o

Your Browser will spin up and shows URL: http://localhost:4200

What you see here is the Angular demo website.

Put it all together

Frontend: Load Data from Backend

Open cmd in c:\temp\myAngular9NetCore3App\frontend. Enter “code .” to spin up VS Code in the right folder:

  1. rem 'code .' starts VS Code and sets the current folder as work directory
  2. cd c:\temp\myAngular9NetCore3App\frontend
  3. code .

Press Control-C in cmd or close browser to stop the web app.
Edit \src\app\app.module.ts: Add HttpClientModule:

  1. ...
  2. import { HttpClientModule } from '@angular/common/http';
  3. imports: [
  4. ...
  5. HttpClientModule
  6. ],

Call the backend: add some imports to app.component.ts;

  1. import { Component, Inject } from '@angular/core';
  2. import { HttpClient } from '@angular/common/http';

And add a constructor to the class, which gets the HttpClient injected:

  1. constructor(http: HttpClient) {
  2. http.get<any[]>('https://localhost:5001/weatherforecast').subscribe(result => {
  3. console.warn("weatherforecast", result);
  4. }, error => console.error(error));
  5. }

The code will look like this:

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)); } }

Check new Angular app

If it is not already running, start .NET Core Backend by pressing F5 in Visual Studio.

Now start frontend project:

  1. rem Go to the frontend folder
  2. cd c:\temp\myAngular9NetCore3App\frontend
  3. rem s: serve
  4. rem o: open browser
  5. rem This will spin up a web server and a browser on http://localhost:4200
  6. 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 error

Fix CORS error

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):

  1. readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
  2. public void ConfigureServices(IServiceCollection services)
  3. {
  4. services.AddCors(options =>
  5. {
  6. options.AddPolicy(name: MyAllowSpecificOrigins,
  7. builder =>
  8. {
  9. builder.WithOrigins("http://localhost:4200"); // Frontend URL
  10. });
  11. });
  12. services.AddControllers();
  13. }

Use CORS Policy in Configure (Startup.cs):

  1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  2. {
  3. ...
  4. app.UseRouting();
  5. app.UseCors(MyAllowSpecificOrigins); // AFTER app.UseRouting();
  6. ...
  7. }

Fine tune CORS

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.

  • Only allow the headers you need
  • Only allow the methods you need
  1. options.AddPolicy(name: MyAllowSpecificOrigins,
  2. builder =>
  3. {
  4. builder.WithOrigins("http://localhost:4200") // Frontend URL
  5. .AllowAnyHeader() // allow any Header
  6. .AllowAnyMethod(); // also allow PUT and POST and other methods
  7. // .WithMethods("PUT", "GET"); allow PUT and GET only
  8. });

Check the application

  1. Start your new Backend
  2. Start your new Frontend
  3. Check Console Output: you should see an array of data:

Success :)

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 <a href=@patrikbo"> @patrikbo. Thank you!

Whats next

Swagger/OpenApi are tools which can create your Angular code to access the backend: check this https://github.com/boeschenstein/angular9-dotnetcore-openapi-swagger

Additional Information

Current Versions

  • Visual Studio 2019 16.5.3
  • .NET core 3.1
  • npm 6.14.4
  • node 12.16.1
  • Angular CLI 9.1