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