0

For some context I'm developing a web app using Angular and .net where I retrieve some data out of the database and I'm able to search it using a search bar.

My problem is on CORS I implemented it on .net and I can use the GET method but I'm not able to use PUT method and other methods like POST and DELETE but I'm able to do it on Postman (But that is right because from what I saw Postman have no restrictions in terms of CORS). I got this error on webconsole.

Access to XMLHttpRequest at 'https://localhost:44312/api/Collaborator/7' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here is my .net code

using System;
using FluentValidation.AspNetCore;
using MediatR;
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OB.TimeSheet.Application;
using OB.TimeSheet.Application.Common.Interfaces;
using OB.TimeSheet.Infrastructure;
using OB.TimeSheet.Infrastructure.Data;
using OB.TimeSheet.src.Application.Common.Interfaces;
using OB.TimeSheet.WebUI.Services;

 namespace OB.TimeSheet.WebUI
{
    public class Startup
  {
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplication();
        services.AddInfrastructure(Configuration);

        services.AddDbContext<OBDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("MyDbContext")));

        services.AddScoped<IApplicationDbContext, OBDbContext>();

        services.AddRouting();

        services.AddCors(options =>
        {
            options.AddPolicy("OBTimesheetPolicy", builder =>
            {
                builder.WithOrigins("http://localhost:4200") // Add your Angular application's origin
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });
        });

        services.AddMediatR(typeof(Startup));

        services.AddSingleton<ICurrentUserService, CurrentUserService>();

        services.AddHttpContextAccessor();

        services.AddHealthChecks();

        services.AddSwaggerGen();

        services.AddControllers()
            .AddFluentValidation();

        services.AddFluentValidationAutoValidation()
            .AddFluentValidationClientsideAdapters();

        services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
            .AddNegotiate();

        services.AddAuthorization(options =>
        {
            options.AddPolicy("AllUsers", policy => policy.RequireAuthenticatedUser());
        });

        services.AddRazorPages();

        services.Configure<ApiBehaviorOptions>(options =>
        {
            options.SuppressModelStateInvalidFilter = true;
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseCors("OBTimesheetPolicy");

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();

            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");

            endpoints.MapControllerRoute(
                name: "api",
                pattern: "api/{controller}/{action=Index}/{id?}");

            endpoints.MapRazorPages();
        });

        app.UseHealthChecks("/health");

        app.UseSwagger();
        app.UseSwaggerUI(options =>
        {
            options.DocumentTitle = "OB.TimeSheet API";
            options.RoutePrefix = string.Empty;

            options.DisplayOperationId();
            options.DisplayRequestDuration();

            options.SwaggerEndpoint("/swagger/v1/swagger.json", "OB.TimeSheet API V1");
        });
    }
}

}

And Angular

import { Injectable } from '@angular/core';
import { Collaborator, Team } from 'src/app/models/api/api.models';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

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

  private readonly options = {withCredentials: true};  
  private readonly apiUrl: string = environment.apiUrl;

  constructor(private httpClient: HttpClient) {}

  getCollaborator(): Observable<Collaborator[]> {
    return this.get<Collaborator[]>('/Collaborator');
  }

  updateCollaborator(collaborator: Collaborator): Observable<void> {
    return this.put<void>(`/Collaborator/${collaborator.id}`, collaborator);
  }

  getTeam(): Observable<Team[]> {
    return this.get<Team[]>('/Team');
  }

  private get<T>(endpoint: string): Observable<T> {
    return this.httpClient.get<T>(this.apiUrl + endpoint, this.options);
  }

  private put<T>(endpoint: string, body: any): Observable<T> {
    return this.httpClient.put<T>(this.apiUrl + endpoint, body, this.options);
  }
}
  • It might be a HTTP to HTTPS thing. Have you tried hosting your Angular app locally under HTTPS and adding `https://localhost:4200` to your CORS config? See https://stackoverflow.com/questions/8414786/javascript-cross-domain-call-call-from-http-to-https for more info. – phuzi Jun 12 '23 at 10:21
  • @phuzi I'll try that and then I'll give feedback – Bernardo Pereira Jun 12 '23 at 10:29
  • @phuzi No, because the error message clearly states that the request comes from `http://localhost:4200`. – jub0bs Jun 12 '23 at 18:56
  • @jub0bs Not quite sure what you mean. I'm suggesting that OP moves the Angular site to HTTPS so that the HTTP site to HTTPS server becomes HTTPS site to HTTPS server. – phuzi Jun 12 '23 at 20:23
  • @phuzi Although that is good advice, that will not fix the OP's CORS issue, that's all I'm saying. – jub0bs Jun 13 '23 at 06:45
  • @jub0bs Which is why it was a comment as something to try. – phuzi Jun 13 '23 at 07:48
  • @jub0bs That's true, I didn't test it to change to https because I talked to front end and back end devs and they said the same thing – Bernardo Pereira Jun 14 '23 at 14:28
  • @jub0bs I've tried everything by now and cant get past this error, idk what is causing it since CORS is configured correctly – Bernardo Pereira Jun 14 '23 at 14:29

1 Answers1

-1

Try to update your Cors-Policy like this:

builder.Services.AddCors(options =>
{
    options.AddPolicy("OBTimesheetPolicy",
        builder => builder
        .SetIsOriginAllowed((host) => true)
        .WithOrigins("https://localhost", "http://localhost")
        .AllowAnyMethod()
        .WithExposedHeaders(HeaderNames.ContentDisposition)
        .AllowAnyHeader());
});
Kajen
  • 39
  • 6