Connecting an Angular and ASP.NET Core App

In this post we are going to set up an Angular app and an ASP.NET Core app so that they can communicate with each other.

The first thing we need to do is create the applications.

Creating the Web API

Let’s create our Web API first. To do that, we can use Visual Studio 2022, and select the Web API template on the create a new project screen.

The first thing we need to do is configure CORS. CORS, which stands for Cross-Origin Resource Sharing, is a security mechanism that allows us to indicate from which origins we want to be able to receive HTTP requests. For example, if my Angular app will be at http://localhost:4200/, then I must configure my Web API to allow these requests from that domain.

To configure CORS, we go to the Program class and say:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();

// A
var allowedOrigins = builder.Configuration.GetValue<string>("allowedOrigins")!.Split(",");

// B
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.WithOrigins(allowedOrigins).AllowAnyHeader().AllowAnyMethod();
    });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();

// C
app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

From the code above, what we are interested in are the parts I have marked with A, B, and C. The variable allowedOrigins will contain the different origins (this is similar to domains) which will be able to communicate with our Web API. On the other hand, with the builder.Services.AddCors we are enabling CORS in our Web API, and, we are configuring it to allow the origins that are in allowedOrigins, in addition to allowing any header and any HTTP method from the client. Finally, in part C, we have app.UseCors, where we configure the corresponding Middleware to be able to use CORS.

Then, we can go to appSettings.Development.json and place the origins that we want to allow to communicate with our Web API:

 "allowedOrigins": "http://localhost:4200"

With this, we can run our app by pressing CTRL+F5. If the Web API does not open automatically, you can go to the launchSettings file located in the Properties folder, and modify the profile you use to open the browser:

"launchBrowser": true,

With this, close the console and run the App again so that it opens automatically in your browser.

Creating the Angular App

To create an Angular app, open a terminal and type:

ng new app-de-angular

We will configure the app to use CSS, we will not use Server-Side Rendering.

When the app is finished creating, go to the project folder in the terminal and run the following command:

ng generate environments

With this command you can generate environment variable files. These will allow us to place the URL of our Web API in a centralized way in one place. In addition, we can have several “versions” of the Web API URLs: one for the development environment, and another for production.

Tip: If you have your app running when you run the previous command, you must stop running it and run it again so that it assumes the newly created environment files.

Now, let’s go into the newly created .env extension files and put the following:

// file: environment.development.ts
export const environment = {
    apiURL: 'https://localhost:XXXX'
};
 
// file: environment.ts
export const environment = {
     apiURL: 'PENDING'
};

In the environment.development.ts file you will place the Web API URL. You will find this either in the Web API console or in the browser that opened when running the ASP.NET Core app. In the environment.ts file we will place the production Web API URL, since we do not have one, we will put PENDING.

With this we have established the communication between our Web API and our Angular app. Let’s test this.

Testing the Implementation

To test, we just need to make an HTTP request from the Angular app to the Web API. We can consume the default endpoint that is created related to weather test data. To do this, we can create a service:

ng generate service weatherforecast --skip-tests

This service will encapsulate the implementation details to communicate with the Web API.

Then, since we want to be able to use the HttpClient in this newly created class, we need to configure it. To do this, we go to app.config.ts and put this:

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
 
import { routes } from './app.routes';
import { provideHttpClient, withFetch } from '@angular/common/http';
 
export const appConfig: ApplicationConfig = {
  providers: [provideZoneChangeDetection({ eventCoalescing: true }), 
    provideRouter(routes),
    provideHttpClient(withFetch()) // <--
  ]
};

Then, in the WeatherforecastService class:

import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { environment } from '../environments/environment';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class WeatherforecastService {

  constructor() { }
  private http = inject(HttpClient);
  private apiUrl = environment.apiURL + '/weatherforecast';

  public get(): Observable<any> {
    return this.http.get(this.apiUrl);
  }
}

Then, we can consume this service from any component, such as App.Component. In the component class we place:

import { Component, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { WeatherforecastService } from './weatherforecast.service';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'my-angular-app';
  weatherForecasts: any[] = [];

  weatherForecastService = inject(WeatherforecastService);

  constructor(){
    this.weatherForecastService.get().subscribe(weatherForecasts => {
      this.weatherForecasts = weatherForecasts;
    });
  }

}

And in the template:

<h2>Testing the communication between Angular and ASP.NET Core</h2>

@for (weatherForecast of weatherForecasts; track $index) {
  <div>
    <div>
      Date: {{weatherForecast.date}}
    </div>
    <div>
      Temperature (C): {{weatherForecast.temperatureC}} 
    </div>
    <div>
      Summary: {{weatherForecast.summary}}
    </div>
  </div>
  <hr>
}

And now we can run the Angular app and test it.

If you want to learn more about developing Angular and ASP.NET Core applications, buy my Udemy course today, the following link has a discount included: https://felipe-gavilan.azurewebsites.net/api/Redireccion?curso=angular-and-asp-net-core

Thanks!

Leave a comment