Azure Internal Server Error on ASP.NET Core Web API Controller - reactjs

I've created a ASP.NET Core Web API Controller with React Js App and it on Azure. After sever try I am able to upload on Azure and now I'm getting error on my API. When I click on Customer it does not give me error but there is no data from SQL Database.
Can someone guide me on How to connect DB to my ASP.NET Core Web API or suggest me where am I doing wrong?
I tried post/add data to customer table but I am getting Internal server Error
Here is sql connection string in my appsetting.json
"ConnectionStrings": {
"DevConnection": "jdbc:sqlserver://aspapireact.database.windows.net:1433;database=ReactTask;user=*****;password=*****;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"}
The Startup.cs
namespace RahulTask1
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddControllers();
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.WithOrigins("https://aspapireact.azurewebsites.net")
.AllowAnyMethod()
.AllowAnyHeader();
});
});
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// 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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
}
And this the API I am trying to call
https://aspapireact.azurewebsites.net/api/Customers
You can see my code on GitHub
https://github.com/rlbrs/ASPAPIReact
In this project you will see the local server connection string but I've updated with above one and same with appserver.json

you can use the configuration builder to the configure services method. To build the key value pair from the appsettings.json on any environment based appsettings file, add following code to the ConfigureServices method (This is not mandatory)
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false , reloadOnChange : true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
And then you read the value for the connection string as
Configuration["ConnectionStrings:DevConnection"]
PS: Any particular reason you are using jdbc connection? why not use the standard dot net based connection string?

Related

Unable to consume .NET Core web API in React JS After Single Sign on using Azure Ad

I have successfully implemented Single Sign on with Azure Ad and fetched profile using MS Graph API but when I try to consume my dot net web API it is showing me error Unauthorized(401)
May be I am missing something in configuration,
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "example.onmicrosoft.com",
"ClientId": "392xxxx2-bxx4-4xxf-axxc-505bd9c6d8b4",
"TenantId": "06xxx2xbe-9xxe-4xx8-bxxd-e1a6ebxxxxd",
"scopes": "api://3xxxxe52-bxx4-4xxf-axx2c-505bxxxxb4/User.Read"
}
here is my Startup.cs code
using AutoMapper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using TMS.API.Configuration;
using TMS.DAL.Configuration;
using TMS.DAL.Mapper;
using Microsoft.Identity.Web;
namespace TMS.API
{
public class Startup
{
public Startup(IConfiguration configuration) => Configuration = configuration;
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.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApi(Configuration, "AzureAd");
services.AddControllers();
services.AddSwaggerGen(s =>
{
s.SwaggerDoc("v1", new OpenApiInfo() { Title = "TMS API", Version = "V1" });
});
services.AddAutoMapper(typeof(Startup));
services.Configure<Setting>(Configuration.GetSection("Settings"));
services.RegisterEngineServices();
services.RegisterRepositories();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithHeaders()
.WithExposedHeaders());
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "TMS v1");
});
}
private static void AddAutoMapper(IServiceCollection services)
{
var mapperConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new BSRMapperClass());
});
IMapper mapper = mapperConfig.CreateMapper();
services.AddSingleton(mapper);
}
}
}
Controller:
[Route("api/[controller]")]
[ApiController]
[RequiredScope(RequiredScopesConfigurationKey ="AzureAd:scopes")]
public class GeneralController : ControllerBase
{
private readonly IConfiguration _configuration;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IGeneralService _generalService;
public GeneralController(IGeneralService generalService, IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
{
_generalService = generalService;
_configuration = configuration;
_httpContextAccessor = httpContextAccessor;
}
[Authorize(Roles ="Admin")]
[Route("[action]")]
[HttpGet]
public async Task<DataTransfer<IEnumerable<MonthResponseModel>>> GetMonthList()
{
return await _generalService.GetMonthList();
}
React config file:
export const msalConfig = {
auth: {
clientId: "ddxxxx8-xxf-4xxd-bxx2-a4xxxxxd6c",
authority: "https://login.microsoftonline.com/061f82be-9xxe-4xx8-bdad-e1xxxxxb6d", // This is a URL (e.g. https://login.microsoftonline.com/{your tenant ID})
redirectUri: "http://localhost:3001",
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
}
};
export const apiConfig = {
uri: "https://example.azurewebsites.net/api", // e.g. http://localhost:5000/api
scopes: ["api://3xxxx2-bxx4-4xxf-a72c-505xxxxx8b4/User.Read"] // e.g. ["scp1", "scp2"]
};
// Add scopes here for ID token to be used at Microsoft identity platform endpoints.
export const loginRequest = {
scopes: ["User.Read"]
};
// Add the endpoints here for Microsoft Graph API services you'd like to use.
export const graphConfig = {
graphMeEndpoint: "https://graph.microsoft.com/v1.0/me"
};
Here we have:
Client(React) App Essentials
Server(.net web API) App Essentials
I have exposed my API and added scope and authorized client Application:
Exposed API
I need help as I have been stuck in this issue from a couple of days and Kindly do let me know where to add Users in Client App or in Server app?
Issue Fixed!
In appsetting I changed "scopes": "api://3xxx52-bxx4-40xf-axxc-505xxxx8b4/User.Read" to "scopes": "User.Read"and reorder the middleware in Configure Method (Startup file):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Loreal TMS v1");
});
app.UseHttpsRedirection();
//app.UseStaticFiles();
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

ASP.NET 6 + React APIs

I have been struggling to integrate React with ASP.NET 6
Finally I am using the following configuration at Program.cs
app.UseSpa(spa =>
{
spa.Options.SourcePath = "FrontEnd";
if (builder.Environment.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
and had WDS_SOCKET_PORT=7207 in the .env.development file of the frontend to refresh the page with every code update
Now my problem is that all APIs respond with 404 (it worked previously very well as WebAPI app without React)
I don't think that I am pointing to a wrong port, knowing that I am using the port the is in "applicationUrl": "https://localhost:7207"
I think the routing configuration needs to be adjusted
Can't solve it
====
AS requested here is the Program.js
using EBankingSystem.Data;
using EBankingSystem.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;
// Add services to the container.
// DB
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(configuration.GetConnectionString("Development")));
services.AddDatabaseDeveloperPageExceptionFilter();
// View
In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "FrontEnd/build";
});
// Controllers
services.AddControllers();
// Identity
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
// 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.UseDefaultFiles();
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "FrontEnd";
if (builder.Environment.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

HTTP Error 500 when deploying ASP.NET Core 2.2 to additional Azure Web App

I have already deployed the application to a Azure web app that works just fine. I am using an ASP.NET Core 2.2 application with MVC connected to a SQL server located on Azure. I am working with dotnet SDK version 3.1.301.
The application has a React client. I am trying to make the application multi - tenancy, therefore, each web app has its own Azure Key Vault but a single database. All of the environment variables are located within the key vault, including the connection string to the db.
I have created an additional web app on Azure (this one is for production) connected to an additional Key Vault. After deploying to this web app, I get a HTTP 500 error. In the web activity logs I do not receive any errors. I am using Microsoft Visual 2019 to deploy the applications.
My question is; I have followed all the same steps for the first deployment and I would really like to know why, when spinning up a new app with a new key vault, why I am not getting any errors?
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
if (context.HostingEnvironment.IsProduction())
{
var builtConfig = config.Build();
var keyVaultUri = builtConfig.GetValue<string>("KEY_VAULT_URI"); //Connection to KEY VAULT
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
config.AddAzureKeyVault(keyVaultUri, keyVaultClient, new DefaultKeyVaultSecretManager());
}
}
).UseStartup<Startup>();
}
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddTransient<ILearnerService, LearnerService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
// Fixed Unexpected end of JSON
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddDbContext<DataContext>(
option => option.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddAutoMapper();
services.AddCors();
// Configure DI for application services
services.AddScoped<ILearnerService, LearnerService>();
// In production, the React files will be served from this directory **********
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
// Configure strongly typed settings objects
var appSettingsSection = Configuration;
services.Configure<AppSettings>(appSettingsSection);
services.AddMultiTenancy()
.WithResolutionStrategy<HostResolutionStrategy>()
.WithStore<InMemoryTenantStore>();
// Configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
var encryptionKey = Encoding.UTF8.GetBytes(appSettings.EncryptionSecret);
services.AddAuthorization(options =>
{
options.AddPolicy(TenantFeatures.Inbox, policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser()
.RequireAssertion(context =>
context.User.HasClaim(TenantFeatures.Inbox, "user.Stores.Companies"))
.Build();
});
});
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var learnerService = context.HttpContext.RequestServices.GetRequiredService<ILearnerService>();
var userId = int.Parse(context.Principal.Identity.Name);
var user = learnerService.GetById(userId);
if (user == null)
{
// Return unauthorized if user no longer exists
context.Fail("Unauthorized");
}
// user.Stores.Companies
var tenantInfo = Configuration.GetValue<string>("tesco-training-net");
if (tenantInfo.Contains(TenantFeatures.Inbox))
{
Claim claim = new Claim(TenantFeatures.Inbox, "user.Stores.Companies");
((ClaimsIdentity)context.Principal.Identity).AddClaim(claim);
}
if (tenantInfo.Contains(TenantFeatures.DynamicCV))
{
Claim claim = new Claim(TenantFeatures.DynamicCV, "user.Stores.Companies");
((ClaimsIdentity)context.Principal.Identity).AddClaim(claim);
}
return Task.CompletedTask;
}
};
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
RequireSignedTokens = true,
// Fixed [Authorize] decrypts the tokens
TokenDecryptionKey = new SymmetricSecurityKey(encryptionKey),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"]);
services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"]);
}
// This method gets called by the runtime. Use this method to Configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthentication();
app.UseMultiTenancy();
app.UseMvc();
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
EDIT
Within the Application logs, I am getting this:
IIS was not able to access the web.config file for the Web site or
application. This can occur if the NTFS permissions are set incorrectly.
IIS was not able to process configuration for the Web site or application.
The authenticated user does not have permission to use this DLL. The request is mapped to a managed handler but the .NET Extensibility Feature is not installed. Things you can try: Ensure that the NTFS permissions for the web.config file are correct and allow access to the Web server's machine account. Check the event logs to see if any additional information was logged. Verify the permissions for the DLL. Install the .NET Extensibility feature if the request is mapped to a managed handler. Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click here.

SignalR Hub not receiving user from client WPF (.netcore 3.1)

I have a WPF client which connects successfully to a Hub, but I cannot pass the user of the client to the Hub.
My connection.User?.Identity?.Name in my class implementing from IUserIdProvider returns null.
For my WPF client I use this to connect against the Hub:
_connection = new HubConnectionBuilder()
.WithUrl(viewModel.Endpoint, opts =>
{
opts.Credentials = new NetworkCredential("user", "password", "domain");
opts.UseDefaultCredentials = true;
})
.Build();
I have then the following provider registered as singleton:
public class NameUserIdProvider : IUserIdProvider
{
public string GetUserId(HubConnectionContext connection)
{
return connection.User?.Identity?.Name;
}
}
As I mentioned above, the connection.User?.Identity?.Name; is returning null.
I don't know what else I can do to pass the user name from my client (WPF) to my Hub.
By the way, my Startup.cs looks like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddLogging();
services.AddSingleton<IUserIdProvider, NameUserIdProvider>();
services.AddSignalR(hubOptions =>
{
hubOptions.EnableDetailedErrors = true;
});
services.AddScoped<IBuildsService, BuildsService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<SyncCodeHub>("/signalr");
});
}
Any help would be much appreciated.
EDIT:
I update the code with:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
But the problem continues, the identity user (IUserIdProvider) is returning null when called from the WPF client. I'm running the API locally with IISExpress.
EDIT:
From Microsoft docs:
Windows Authentication is only supported by the browser client when using Microsoft Internet Explorer or Microsoft Edge.
So I'm wondering if this is even possible with an Desktop as a client. I assume it should work, so I'm wondering if I'm still missing a point or if this is a bug related to the Version of SignalR I#m using (3.1.3)
You need to configure your ASP.NET Core app to use Windows authentication by calling AddAuthentication in the ConfigureServices method of the Startup class:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
You should also edit your launchSettings.json file according to the docs:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:52171/",
"sslPort": 44308
}
}

Access HangFire endpoint from Visual Studio 2019 React template project

Following the guide at https://medium.com/#jamesdale1993/asp-net-core-2-with-signalr-and-react-redux-a-simple-example-c25ea6b19dbe I created a project with Visual Studio 2019 and the react-redux template (core 3.0 project).
I got the SignalR up and running as per article, react frontend connected to SignalR endpoint in backend code.
I then installed HangFire (https://www.hangfire.io/), set it up, and the recurring job set up for testing is working correctly. I can see (in database) the recurring job firing every minute as it should.
My problem:
I cannot access HangFire Dashboard! By default it should be http://localhost:55663/hangfire, but I see only header of template project.
I guess it is some kind of routing issue as I can only access what is served in ClientApp/build folder (react).
Any help would be greatly appreciated.
I've tried to change the default /hangfire endpoint by setting
app.UseHangfireDashboard("/jobs"); in Startup.cs Configure section, same result.
In Startup.cs code below, search for "Hangfire" for relevant sections.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddSignalR();
services.AddControllersWithViews();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// Database connection
services.AddTransient<IDbConnection>((sp) =>
new SqlConnection(Configuration.GetConnectionString("TestProjectConnection"))
);
// Hangfire
services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString("TestProjectConnection")));
services.AddHangfireServer();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
[System.Obsolete]
public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// 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.UseCors("MyPolicy");
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
//Hangfire endpoint
app.UseHangfireDashboard("/jobs");
//backgroundJobs.Enqueue(() => Debug.WriteLine("Hello world from Hangfire!"));
RecurringJob.AddOrUpdate<ITestClass>("TestMethod", x => x.WriteMessage("Testing"), Cron.MinuteInterval(1));
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSignalR(routes =>
{
routes.MapHub<SignalRCounter>("/signalrcounter");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp/build";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
It was a matter of order of the routes.
Working with:
public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// 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.UseCors("MyPolicy");
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSignalR(routes =>
{
routes.MapHub<SignalRCounter>("/signalrcounter");
});
app.UseHangfireDashboard("/hangfire");
app.UseRewriter();
app.UseAuthentication();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp/build";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
app.UseHangfireServer();
//backgroundJobs.Enqueue(() => Debug.WriteLine("Hello world from Hangfire!"));
RecurringJob.AddOrUpdate<ITestClass>("TestMethod", x => x.WriteMessage("Testing"), Cron.MinuteInterval(1));
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
}

Resources