I am currently working on an .Net Core WebAPI Project (netcore 2.0) and I want to define the URL my application runs on in my appsettings.json file. I then use the following code in my Program.cs file:
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json").Build();
var url = config.GetSection("WebAppSettings").GetValue<string>("Url");
var host = new WebHostBuilder()
.UseUrls(url)
.UseIISIntegration()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((context, configBuilder) =>
{
configBuilder
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseStartup<Startup>()
.UseNLog()
.Build();
host.Run();
My appsettings.json file:
{
"WebAppSettings": {
"Url": "http://localhost:5023"
}
}
However, when I run my application, it is only accessible on port 5022 (I previously set it to this but changed it to 5023 afterwards). When I look into my project properties and go to the "Debug" submenu, it states 5022 as the port. I tried erasing this property but it's an required field.
So how can I force Visual Studio to use the port I set in my appsettings.json file without it screwing up my settings?
IIS Express uses launchSettings.json, which itself is set via the project properties settings you mentioned. UseUrls only applies outside of Visual Studio/IIS Express.
Related
I have a small Blazor WASM project that I recently migrated to .net 6. But now I tried to run the published project and the application warned me that I don't have a license for Duende Identity Server.
My question is:
Can I do without the Duende Identity Server?
In my application, I need user login and role assignment. I want to have users defined only for this application and I want to use the application database to store them.
My Program.cs looks like this:
var builder = WebApplication.CreateBuilder(args);
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
var appDbConStr = builder.Configuration.GetConnectionString("AppDbConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(appDbConStr));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddClaimsPrincipalFactory<AppClaimsPrincipalFactory>();
builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, AppDbContext>(opt =>
{
opt.IdentityResources["openid"].UserClaims.Add(UserClaim.Role);
opt.ApiResources.Single().UserClaims.Add(UserClaim.Role);
opt.IdentityResources["openid"].UserClaims.Add(UserClaim.Avatar);
opt.ApiResources.Single().UserClaims.Add(UserClaim.Avatar);
opt.IdentityResources["openid"].UserClaims.Add(UserClaim.Nick);
opt.ApiResources.Single().UserClaims.Add(UserClaim.Nick);
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
builder.Services.AddAuthentication().AddIdentityServerJwt();
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddTransient<IRazorRendererHelper, RazorRendererHelper>();
builder.Services.AddScoped<Vks.Server.Services.SerialGenerator>();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.Run();
Thank you
Use default ASP.NET CORE Identity (do not add reference to Duende).
Must read article covers all features of ASP.NET CORE Identity
https://chsakell.com/2018/04/28/asp-net-core-identity-series-getting-started/
Remove Duende reference by deleting reference on Microsoft.AspNetCore.ApiAuthorization.IdentityServer (duende is sub referenced)
Add asp.net core identity as follow:
builder.Services
.AddIdentity<ApplicationUser<int>, ApplicationRole>(config =>
{
config.SignIn.RequireConfirmedEmail = false;
config.Lockout.AllowedForNewUsers = true;
config.Lockout.MaxFailedAccessAttempts = 3;
config.User.RequireUniqueEmail = true;
config.Password.RequiredLength = 8;
//...other opts//
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserManager<CustomUserManager>() // inherited from UserManager with overriden logic
.AddDefaultTokenProviders()
.AddTokenProvider<CustomAuthenticatorTokenProvider>(TokenOptions.DefaultAuthenticatorProvider) // inherited from AuthenticatorTokenProvider with overriden logic
.AddPasswordValidator<CustomPasswordValidator>(); // implements IPasswordValidator for additional password validation
Log works well locally.
This is how I deploy to iis:
Right click on Visual Studio project > publish to "publish" folder
Copy all files from "publish" folder to the server as zip.
On the server > open iis > stop that specific website
Delete the existing files on the website's physical path
Unzip the files to the website's physical path
Start the website.
When I start the website and send a POST request from postman, the first time the log works as expected, generates all log including HealthCheck and everything. But further calls are not logging. If I restart the website from iis, it again works once and stops logging further requests.
Otherwise the api works as expected, I see data in the database.
appSettings.json
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Verbose",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "./log/mywebapi.log",
"rollingInterval": "Day",
"maximiumFileSize": 500000000,
"rollOnFileSizeLimit": true
}
}
]
}
Program.cs
Added .UseSerilog() in Program.cs, not in startup.cs. Not sure if it matters.
public class Program
{
public static IConfiguration Configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", reloadOnChange: true, optional: true)
.AddEnvironmentVariables()
.Build();
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithThreadName()
.Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
.ReadFrom.Configuration(Configuration)
.CreateLogger();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).UseSerilog();
}
I've created a very basic .net CORE WEB API, following a youtube guide.
Everything works fine when I debug from visual studio. it opens my browser and directs me to the swagger ui site.
But when I run outside visual studio, starting the exe from the build/bin folder I can't get to that swagger site.
in a command propt the exe file says it is listening on http on port 5000.
so while this is running go to this url http://localhost:5000/swagger/index.html
anyone have a hit on what I'm missing here ?
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "server=myServerXXXX;database=myDataBaseXXXX;User ID=mydbUserXXXXX;Password=myPasswordXXX"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
program.cs
global using ShoppingList.API.Data;
global using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddDbContext<ShoppingItemDataContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();
By default dotnet runs applications with the production environment and you have swagger enabled for the dev environment only. change the condition or pass the "--environment production" argument (or configure host environment: e.g. https://enlabsoftware.com/development/dotnet-core-environment-how-config-examples.html)
When running a console app outside of a local environment, .net core 3.1 is looking for the appsettings.json file in a different directory than where the program executes.
The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\windows\system32\appsettings.json'.
In previous versions of dotnet using the Environment.CurrentDirectory or Directory.GetCurrentDirectory() but not working in 3.1. How do you change this so that it looks in the directory where it is running? The below does not work
using var host = Host.CreateDefaultBuilder()
.ConfigureHostConfiguration(builder =>
{
builder.SetBasePath(Environment.CurrentDirectory);
builder.AddCommandLine(args);
})
.UseConsoleLifetime(options => options.SuppressStatusMessages = true)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, builder) =>
{
builder.AddJsonFile("appsettings.json");
hostContext.HostingEnvironment.EnvironmentName = Environment.GetEnvironmentVariable("NETCORE_ENVIRONMENT");
if (hostContext.HostingEnvironment.EnvironmentName == Environments.Development)
{
builder.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true);
builder.AddUserSecrets<Program>();
}
})
This seems to work, by getting the base directory from AppDomain.CurrentDomain before setting the base path. I still do not understand why this was not required in previous dotnet versions and I was unable to find any MS documentation on this.
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
using var host = Host.CreateDefaultBuilder()
.ConfigureHostConfiguration(builder =>
{
builder.SetBasePath(Directory.GetCurrentDirectory());
builder.AddCommandLine(args);
})
We add appsettings like this:
public Startup(IWebHostEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
...
}
Just add useStaticfiles() on your builder method; it will resolve your problem:
app.useStaticfiles()
From what I understand the correct way of setting listen ports for ASP Dotnet Core 2 preview 1/2 is by creating a Kestrel section in the appsettings.json in the following format:
"Kestrel": {
"EndPoints": { //Could also be Endpoints, it's a bit unclear
"Http": {
"Address": "127.0.0.1",
"Port": 9001 //the port you want Kestrel to run on
},
I have tried to set up the sample webapp on a Debian machine, but when I start the app, it writes out that the app is listing on port 5000, the default port..
I know that the appsettings.json is read, because when I change the logging level to Trace, I get more info upon startup, including that no Endpoints are found and the app will use the standard 5000 port.
I have tried to search the aspnet source code on Github, and I can find a area where the Kestrel section is read from configuration (https://github.com/aspnet/Identity/blob/e38759b8a2de1b7a4a1c19462e40214b43c1cf3b/samples/IdentityOIDCWebApplicationSample/MetaPackage/KestrelServerOptionsSetup.cs), but as you can see it looks like a sample project.
What am I missing, isn't this the standard way to configure Kestrel in ASP Dotnet core 2?
As mentioned in a comment on the accepted answer, 2.1 has support for appsettings.json, see https://blogs.msdn.microsoft.com/webdev/2018/02/02/asp-net-core-2-1-roadmap/#security
A working appsettings.json:
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://localhost:5555"
}
}
}
This is for a Program.cs using (created by "dotnet new webapi"):
WebHost.CreateDefaultBuilder(args)
Relevant source code in GitHub
https://github.com/aspnet/MetaPackages/blob/master/src/Microsoft.AspNetCore/WebHost.cs#L163
options.Configure(builderContext.Configuration.GetSection("Kestrel"));
and https://github.com/aspnet/MetaPackages/blob/master/src/Microsoft.AspNetCore/WebHost.cs#L169
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
Support for Kestrel configuration via appsettings.json has been dropped in 2.0.
See this issue comment:
kestrel config file support was cut from 2.0.0. Config values need to be read manually in your initialization code.
To get around this, you can do something like this in program.cs:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup < Startup > ()
.UseKestrel((hostingContext, options) =>
{
if (hostingContext.HostingEnvironment.IsDevelopment) {
options.Listen(IPAddress.Loopback, 9001);
options.Listen(IPAddress.Loopback, 9002, listenOptions => {
listenOptions.UseHttps("certificate.pfx", "password");
});
}
})
.Build();
I am using Program.cs and hosting.json file to configure Kestrel. Example:
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true, reloadOnChange: true)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>();
hosting.json:
{
"urls": "http://localhost:4444;http://localhost:4445;"
}
This above is an example for the latest version dotnet core.
For earlier versions:
hosting.json:
{
"server.urls": "http://localhost:4444;http://localhost:4445;"
}
To run Visual Studio with Kestrel, just edit appsettings.json and add the config like this (tested with NetCore 2.0 and 2.1):
"profiles" : {
"Kestrel": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:6969/"
}
}
I had the same issue whereby my Kestrel configuration in appsettings.json is not being picked up. From this article about migrating from asp.net core 2.0 to 2.1, I updated the bootstraping code to become like the below, and it worked for me.
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}