.net core 3.0 appsettings.json per environment - .net-core

I want to read in an environment specific appsettings.json based on ASPNETCORE_ENVIRONMENT.
The example Microsoft gives for startup.cs is as follows for core 3.0:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
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.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
In previous versions, code I have seen to add an environmental specific appsettings.json is:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
How would I change the standard Microsoft example to include this?

"environment specific appsettings.json based on ASPNETCORE_ENVIRONMENT" is already done by convention by the call CreateDefaultBuilder() in your Program.cs file.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.0#default-configuration
So you do not need to do anything else. Just set up your ASPNETCORE_ENVIRONMENT value

Related

How to get Blazor HotReload to work with Startup class

I have a Blazor WebAssembly app which is hosted by a .net Core app. I've been upgrading it from .net 6.0 and was using a Startup class to initialize the server app
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args)
.Build()
.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(conf =>
{
conf.AddJsonFile($"appsettings.{Environment.MachineName}.json", optional: true, reloadOnChange: true);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
WebHostEnvironment = environment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
/*Other services registered here*/
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Configure the HTTP request pipeline.
if (env.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
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.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}
Now when I run this app, I can't get hot reloading of Blazor or CSS at all.
What I've found is that if I use the newer pattern implementing WebApplication.CreateBuilder, hot reloading works.
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
ConfigureServices(builder.Services, builder.Configuration);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
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.UseBlazorFrameworkFiles();
app.UseStaticFiles();
var imagesPhysicalPath = app.Configuration.GetSection("ImagesDirectoryPath").Get<string>(); ;
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
RequestPath = "/product-images",
FileProvider = new PhysicalFileProvider(imagesPhysicalPath)
});
app.UseRouting();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.Run();
}
I marginally prefer the former version as it allows me to customise the Configuration mechanism.
Can anyone tell me what I'm missing in the original setup that might have broken the hot reload process?

IHttpContextAccessor.HttpContext is null

I'm using DotNet 5.0, and even though I register HttpContextAccessor in the Startup.ConfigureServices whenever I try to reach it inside the code, IHttpContextAccessor.HttpContext is always null.
This is my Startup.cs file's ConfigureServices Method
public void ConfigureServices(IServiceCollection services)
{
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
this.Configuration = new ConfigurationBuilder().SetBasePath(System.IO.Directory.GetCurrentDirectory()).AddJsonFile($"appsettings.{environmentName}.json").Build();
services.AddControllers();
services.AddSimpleInjector(container, options =>
{
options.AddAspNetCore();
});
services.AddHttpContextAccessor();
}
And this is the Configure method of the same file:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSimpleInjector(container);
container.Verify();
}
And also I'm using hangfire, but whenever a job gets triggered I cannot reach HttpContextAccessor through dependency injection. It is always null.
For example this is one of my business layer files:
public class FooService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public FooService(IHttpContextAccessor httpContextAcessor)
{
_httpContextAccessor = httpContextAccessor;
}
public DoSomething()
{
var tryoutVar = _httpContextAccessor.HttpContext;
}
}
The tryoutVar variable is set to null, always.
Why is this happening?

ASP.net Core Bearer error="invalid_token", error_description="The signature is invalid"

I am using Azure AD for authentication in my ASP.net core app. I can retrieve a token from Azure using postman but when I go to make a request I get the following errror:
"Bearer error="invalid_token", error_description="The signature is invalid""
Setup.cs
namespace CoreDesk.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(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = "https://sts.windows.net/7d63a3a5-79de-44c2-b5a3-ec21f4d24329/";
options.Audience = "00000003-0000-0000-c000-000000000000";
options.TokenValidationParameters.ValidateLifetime = true;
options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// 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
{
// 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(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowCredentials()
.AllowAnyHeader());
app.UseAuthentication();
app.UseMvc();
}
}
}

Swagger failing with Failed to load API definition (yet another thread)

I tried to add swagger to an existing api and after failing alot, i decided to create a new solution, create a new asp.net core 2.2 api and added swagger as per
https://learn.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.2&tabs=visual-studio
The other posts regarding this issue seem all to indicate a situation where there are multiple httpverbs or none, which is not the case with the default valuescontroller. It gives me the error
Failed to load API Definition.
Fetch error, Service unavailable /swagger/v1/swagger.json
The actual json file at api/swagger/v1/swagger.json actually renders correctly
My startup class is
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSwaggerGen(c =>{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.UseMvc();
}
}
Im using Swachbuckle.AspNetCore v 4.01.
String SwaggerEndpoint = "/swagger/v1/swagger.json";
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
SwaggerEndpoint = "/andi/swagger/v1/swagger.json";
}
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint(SwaggerEndpoint, "My API");
//options.RoutePrefix = string.Empty;
});

Can't get dynamic html page by using Self hosted AspNetCore MVC inside console app as Windows Service

Problem: Need to be able to install and run Asp.Net MVC app (which returns a SPA angular app) as Windows Service
Subject: I'm using ASp.Net Core MVC inside Console app and run it as Windows service and it works perfectly fine (all requests are getting to the right place) but return View(); returns empty page instead of the right html.
public class Startup
{
public IContainer ApplicationContainer { get; private set; }
public IConfigurationRoot Configuration { get; private set; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
if (env.IsDevelopment())
{
// This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
Configuration = builder.Build();
}
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddMvc().AddWebApiConventions();
services.AddCors();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var builder = new ContainerBuilder();
builder.Populate(services);
this.ApplicationContainer = builder.Build();
return new AutofacServiceProvider(this.ApplicationContainer);
}
// This method gets called at the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
var listener = app.ServerFeatures.Get<WebListener>();
if (listener != null)
{
listener.AuthenticationManager.AuthenticationSchemes =
AuthenticationSchemes.NTLM;
}
app.UseFileServer();
app.UseCors(builder => builder.AllowAnyOrigin());
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapWebApiRoute(
name: "defaultApi",
template: "api/{controller}/{action}/{id?}");
});
}
}
public class Program
{
public static string ServiceName = "WebApp";
static void Main(string[] args)
{
try
{
var exePath = Process.GetCurrentProcess().MainModule.FileName;
//sure it's not necessary! It was just a try
directoryPath = directoryPath.Replace("\\bin", "");
var directoryPath = Path.GetDirectoryName(exePath);
var httpAddress = "https://localhost";
var httpPort = "10778";
var host = new WebHostBuilder()
.UseWebListener()
.UseWebRoot(directoryPath + "\\wwwroot") //also just a try to navigate it right
.UseContentRoot(directoryPath)
.UseUrls($"{httpAddress}:{httpPort}")
.UseStartup<Startup>()
.Build();
if (Debugger.IsAttached || args.Contains("--debug"))
{
host.Run();
}
else
{
host.RunAsService();
}
}
catch (Exception ex)
{
var exMessage = ex.Message;
}
}
}
The sample project can be downloaded here
UPDATE:
After including app.UseDeveloperExceptionPage(); into Configure method get such list of the errors
Create a new .NET Core Web Application targeting .NET v4.6.1. See screenshot below.
This way you will get an exe web application by default, and it targets .NET v4.6.1.

Resources