I am using signal to get real time data in my angular application and using .net core 2.2 API for back-end but when i run project i get CORS error in browser console.
VehicleHub.cs
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLayer.HubConfig
{
public class VehicleHub:Hub
{
public int id { get; set; }
public string name { get; set; }
public string vehicleType { get; set; }
public string modelNo { get; set; }
public string registrationNo { get; set; }
public int? lcsVehicleNo { get; set; }
public int relationShipOfficerId { get; set; }
public int driverId { get; set; }
public string driverName { get; set; }
public string relationShipOfficerName { get; set; }
public bool isActive { get; set; }
public DateTime createdOn { get; set; }
public string createdBy { get; set; }
public DateTime modifiedOn { get; set; }
public string modifyBy { get; set; }
public int locationId { get; set; }
public int createdById { get; set; }
public int? modifyById { get; set; }
}
}
here is my starup.cs file
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using BusinessLayer.Helpers;
using MatechEssential;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using WebAPICore.Helpers;
using WebAPICore.middleware;
using WebAPICore.Services;
using WebAPICore.Utility;
using BusinessLayer.HubConfig;
namespace WebAPICore
{
public class Startup
{
private readonly IHostingEnvironment _hostingEnvironment;
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = configuration;
_hostingEnvironment = env;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed((host) => true);
}));
services.AddSignalR();
services.AddMvc(options =>
{
options.Filters.Add(new ErrorHandlingFilter());
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
SQLHelper._ConStr = appSettings.ConnectionString != null? appSettings.ConnectionString:"" ;
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = "bearer";
x.DefaultChallengeScheme = "bearer";
})
.AddJwtBearer("bearer", options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Secret)),
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
// TimeSpan.Zero //the default for this setting is 5 minutes
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
options.SaveToken = true;
});
var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);
string absolutePath = compositeProvider.GetFileInfo("/SetupFiles/MasterSetupData.xml").PhysicalPath;
XmlToList.xmlFileType = absolutePath;
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<UserResolverService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory logger)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseApiExceptionHandler(logger);
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseApiExceptionHandler(logger); //use global exception handlers
}
app.UseSignalR(routes =>
{
routes.MapHub<VehicleHub>("/Utility/GetAllVehicles");
});
// global cors policy
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseResponseWrapper();
//app.UseAPIResponseWrapperMiddleware();
app.UseOptions();
app.UseMvc();
}
}
}
I also have tried the below code but nothing happen
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed((host) => true));
});
UtilityController.cs
[Route("api/[controller]")]
[ApiController]
[EnableCors("CorsPolicy")]
public class UtilityController : ControllerBase
{
private UserModel _currentUser;
private IHubContext<VehicleHub> _hub;
public UtilityController(UserResolverService userService, IHubContext<VehicleHub> hub)// , IUserService userService
{
_hub = hub;
_currentUser = userService.getUserInfo();
}
[HttpGet]
[Route("GetAllVehicles")]
public IActionResult GetAllVehicles()
{
try
{
_hub.Clients.All.SendAsync("transferchartdata", UtilityFuncation.GetVehicleAll());
return Ok(new { Message = "Request Completed" });
}
catch (Exception exp)
{
return NotFound(CommonApiResponse.Create(HttpStatusCode.InternalServerError, "Error Date Not Fetch", exp.Message));
}
}
}
I have removed other actions/methods from controller for Stackoverflow
signal-r.service.ts
import { Injectable } from '@angular/core';
import * as signalR from "@aspnet/signalr";
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class SignalRService {
public data: VehicleModel[]
private hubConnection: signalR.HubConnection
options: signalR.IHttpConnectionOptions = {
accessTokenFactory: () => {
let token = localStorage.getItem("token")
return `Bearer ${token}`;
},
};
public startConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:50915/Utility/GetAllVehicles', this.options)
.build();
this.hubConnection
.start()
.then(() => console.log('Connection started'))
.catch(err => console.log('Error while starting connection: ' + err))
}
public addTransferChartDataListener = () => {
this.hubConnection.on('transferchartdata', (data) => {
this.data = data;
console.log(data);
});
}
constructor() { }
}
export interface VehicleModel {
id : any
name : any
vehicleType : any
modelNo : any
registrationNo : any
lcsVehicleNo : any
relationShipOfficerId : any
driverId : any
driverName : any
relationShipOfficerName : any
isActive : any
createdOn : any
createdBy : any
modifiedOn : any
modifyBy : any
locationId : any
createdById : any
modifyById : any
}
App.component.ts
ngOnInit() {
this.signalRService.startConnection();
this.signalRService.addTransferChartDataListener();
this.startHttpRequest();
}
I have removed other methods from App.component for Stackoverflow
nuget package of signalr
angular version of signar
I get this error in my browser console, but when i added the breakpoint on controller it perfectly hits the action for one time only (you can see the response in console)
below is network snapshot for GetAllVehicles that works for first time
below is network snapshot for negotiate that have CORS issue
I have also tried this url but got nothing.