skip to Main Content

I am working on a app consisting of a .NET API and an Angular 16 front-end. It is deployed on a free Microsoft Azure account.

In srcenvironmentsenvironment.prod.ts I have:

export const environment = {
  production: true,
  apiUrl: 'https://localhost:7231',
  baseUrl: 'https://localhost:44427'
};

There is a proxy configuration file that discerns between the ports above:

const { env } = require('process');

const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
  env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:56482';

const PROXY_CONFIG = [
  {
    context: [
      "/auth",
      "/Segment",
      "/_configuration",
      "/.well-known",
      "/Identity",
      "/connect",
      "/ApplyDatabaseMigrations",
      "/_framework",
   ],
    proxyTimeout: 10000,
    target: target,
    secure: false,
    headers: {
      Connection: 'Keep-Alive'
    }
  }
]

module.exports = PROXY_CONFIG;

The app works fine on the local development environment.

I have deployed the API via Visual Stidio’s Publish option and the Angular client from VS Code, with the help of the Azure App Service extension.

The problem

A problem arises when the app is deployed to Azure.

The API URL is https://my-app-api.azurewebsites.net, while the client stays at https://my-app-client.azurewebsites.net.

The problem is that the client and the API do not communicate.

The URL https://my-app-api.azurewebsites.net throws an HTTP ERROR 500 error.

I have added the above URLs in srcenvironmentsenvironment.prod.ts:

export const environment = {
  production: true,
  apiUrl: 'https://my-app-api.azurewebsites.net',
  baseUrl: 'https://my-app-client.azurewebsites.net'
};

It did not fix the problem.

Questions

  1. What am I doing wrong?
  2. What is the most reliable way to fix this issue?

2

Answers


  1. The src/environments/environment.prod.ts is used for defining environment-specific variables for the production build of the application. It typically includes the base URL for the API.

    … But, simply defining the API URL is not enough to establish communication. The Angular app needs a service to handle HTTP requests using this URL (typically using HttpClient: npm install @angular/common/http) to make requests to the API.
    That service utilizes the API URL from the environment.prod.ts file, yes, but the implementation of the service itself is done elsewhere in the code.

    And if the Angular app and the .NET API are hosted on different domains (which is often the case), CORS (Cross-Origin Resource Sharing) needs to be enabled and properly configured on the server-side (.NET API). That is not something that can be handled by Angular’s environment configuration file.

    ┌──────────────────────┐  HTTP     ┌──────────────────────┐  HTTP    ┌─────────────────────┐
    │ Angular 16 Front-End │ ────────> │ .NET API (Azure App) │ <─────── │ Azure SQL Database  │
    └──────────────────────┘ Request   └──────────────────────┘ Response └─────────────────────┘
    

    In your Angular app, create a service that will handle HTTP requests to your .NET API. The convention is to place such services in a directory named services (or similar), often under the app directory.
    For instance, if you are creating a service named ApiService to handle HTTP requests to your .NET API, the file could be named api.service.ts and placed in the src/app/services/ directory. The full path would be src/app/services/api.service.ts.

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { environment } from '../../environments/environment';
    
    @Injectable({
      providedIn: 'root'
    })
    export class ApiService {
      private apiUrl = environment.apiUrl;
    
      constructor(private http: HttpClient) {}
    
      public getData(): Observable<any> {
        return this.http.get(this.apiUrl + '/your-endpoint');
      }
    
      // Additional methods to interact with the API
    }
    

    To allow communication between your Angular app and the .NET API, you need to enable Cross-Origin Resource Sharing (CORS) in your .NET API, typically found in the Startup.cs file in a .NET Core or .NET 5/6 application.

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddCors(options =>
      {
        options.AddPolicy("AllowSpecificOrigin",
          builder => builder.WithOrigins("http://your-angular-app.com")
                   .AllowAnyMethod()
                   .AllowAnyHeader());
      });
    
      // Other service configurations
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      app.UseCors("AllowSpecificOrigin");
    
      // Other middleware
    }
    
    Login or Signup to reply.
  2. Since you have already mentioned that you are receiving a 500 Internal Server Error. It seems that the issue is on the backend side of things.

    I would suggest you to point your .net backend locally into the hosted DB in Azure via the configuration and re-try the request which is getting 500 Internal server errors on the hosted environment with a simple postman request similar to the hosted environment API call.

    Doing so you will be able to find out what is going wrong in that particular request.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search