ASPNETCORE_ENVIRONMENT no longer overrides DOTNET_ENVIRONMENT? - c#

According to the docs, ASPNETCORE_ENVIRONMENT is suppose to override the DOTNET_ENVIRONMENT environment variable. So, I've went ahead and added a DOTNET_ENVIRONMENT entry set to Development on my machine's system environment variables.
On one of my projects, I had to create a new custom profile which should only be used when my app uses Kestrel (ex.: run from within VS). In order for my custom profile to be picked up, I've added the following section to one of the profiles:
"profiles": {
"Grm.ClientManagementSite.Wasm.Server": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7126;http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Local"
}
},
...
}
I've noticed that whenever I run this profile, the environment is always set up as Development (which is defined by the global system entry I've added to the machine's system environment variables).
I've also noticed that if I use the DOTNET_ENVIRONMENT variable, then my custom profile will get picked up. I'm almost positive that my previous setting (using ASPNETCORE_ENVIRONMENT for overriding the profile on the lauchSettings.json) was working when I've created this project. Does anyone know it this is known issue with .NET 7.0?
Thanks.

Yes, starting .NET 7 Preview 3 when using WebApplicationBuilder DOTNET_ varaibles have higher priority then ASPNETCORE_ ones. See this github issue or this breaking change article.
UPD
JIC:
Created an issue in ASP.NET Core repo
Created PR to docs.

Related

Could not to get environment variable in asp.net core web API 6.0

I am working a asp .net core web API 6.0 ( clean architecture project).
This is my appsettings.Production.json and appsettings.Development.json
{
"Tokens": {
"Key": "my-token",
"Issuer": "issuer",
"Audience": "audience",
"ExpirationInMinutes": 1440
},
// removed rest
}
using Microsoft.Extensions.Configuration;
public static IServiceCollection AddTokenAuthentication(this IServiceCollection services, IConfiguration config)
{
var secret = config.GetValue<string>("Tokens:Key"); // this value is null while running in development / production mode.
var key = Encoding.ASCII.GetBytes(secret);
// removed rest
}
The error I got in terminal while running in development/ production environment
Unhandled exception. System.ArgumentNullException: String reference not set to an instance of a String. (Parameter 's') at System.Text.Encoding.GetBytes(String s) at Infrastructure.Files.AuthenticationExtension.AddTokenAuthentication(IServiceCollection services, IConfiguration config) in /src/Infrastructure/Files/AuthenticationExtension.cs:line 14 at Infrastructure.DependencyInjection.AddInfrastructure(IServiceCollection services, IConfiguration configuration) in /src/Infrastructure/DependencyInjection.cs:line 75 at Program.<Main>$(String[] args) in/src/WebApi/Program.cs:line 21 Aborted (core dumped)
Note:
If I hard-code the value of secret like this
var secret = "my-token"; then the project is running fine in both environment.
All of the environment variables are null while running in development and production environment.
Same error for GetConnectionString
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<DbContext>(options =>
options.UseNpgsql(
configuration.GetConnectionString("DefaultConnection"), // this is also null while running in both environment.. If I hard-coded then working fine
b => b.MigrationsAssembly(typeof(DbContext).Assembly.FullName))
.EnableSensitiveDataLogging());
// removed rest
}
Why this is happens?
Is there any mistakes in my code?
Please help me to find the mistake?
EDIT:
I also have tried copied all from appsettings.Development.json and pasted it into appsettings.json
That does not work.
and here is my
launchSettings.json
"WebApi": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebApi-Production": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7152;http://localhost:5105",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
Do you set the environment variable ASPNETCORE_ENVIRONMENT=Production in the production environment?
By default, ASP.NET Core will read config from appsettings.json file and appsettings.Environment.json file(e.g. appsettings.Development.json).
You can set ASPNETCORE_ENVIRONMENT=Production in production environment or set production config in appsettings.json file.
These documents may be help you:
Configuration in ASP.NET Core
Use multiple environments in ASP.NET Core
----------------for example--------------
My appsettings.json
{
"EFCoreSlowQuery": {
"ServiceName": "json",
"SlowQueryThresholdMilliseconds": 10
}
}
Read config in code:
This is really Stupid. I was also running on this issue and been looking for an answer as the value kept getting null from any of the appSettings for almost all day until I reached your post today. What give me the clue was the picture posted by WHENJUN.
If you see the properties of the Configuration object, you can see the 2 appsettings.JSON are filled in his example. So I went ahead and put a breakpoint in my code and realized they are not loading either. Then I just said to myself, it is really stupid, but I am sure c# is looking for the actual root folder and not the application folder of the solution.
So, I moved my Appsettings files outside the folder I was working on since I created my test app on VSCode (this might be better documented somewhere on how to tell your app where these files are Supposed to be picked up from).
So in my case they are looking for the root of my app folder. Once I made the move, Iconfiguration started picking up the Options pattern as expected and I was able to get the values from Appsettings without issues. Thanks WenJun for the Visual, it saved me an all Nighter.
Let me know if this worked for you, here is a screenshot just in case:
Set your UAC to "Never" ... OR
Run VS 2022 as administrator ... we've run into this issue here also.
I'm not sure why UAC prevents a user that is Administrator from running VS 2022 and to access Environment variables ... sounds like an OS bug or VS 2022 bug.

Running .NET 5 Api under Kestrel from Visual Studio 2019 ignores launchSettings.json applicationUrl setting

We are having an "only on my machine" issue that nobody can figure out.
We have a .NET 5 Api that we run under Kestrel for development purposes. On every other dev VM running the API in Visual Studio picks up on the values in launchSettings.json and launches on the correct ports. However on a the VM in question, it only launches on the default 5000/5001 ports.
This is the entry for the launchSettings.json file.
"profiles": {
"My.Api": {
"commandName": "Project",
"environmentVariables": {
"LogStorageAccountConnectionString": "UseDevelopmentStorage=true",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7001;http://localhost:7000"
}
}
I know there is a way to tell dotnet run to explicitly ignore launchSettings.json but could not find a setting in Visual Studio that would trigger that behavior.
We also thought it might be a permissions issue on the folder because they were a bit weird so we cloned our repo into a new folder and set up the Api again to be run locally. It still ran on 5000/5001.
The lot of us are stumped. Any ideas?
I had exactly the same problem also running .NET 5 API (and also a Blazor project) under Kestrel with Visual Studio. For me however it came suddenly - I was running the project successfully for a couple of weeks and then one day it started refusing to honour launchSettings.json and keep running on default 5000/5001.
I have solved this by upgrading Visual Studio from 16.8.3 to 16.8.4. However since I did not have problems initially with 16.8.3 I suspect the problem is not about Visual Studio version. I think that my original installation got corrupted somehow and the upgrade just fixed the corruption.
BTW my launchSetting.json were honoured when I ran the project from command line using dotnet run. I could also use a workaround by setting the port in Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("https://localhost:6000");
});
We ran into this issue too with both .NET 5 and .NET 6 in Visual Studio 2022, and the only thing that worked was to set the (apparently undocumented) variable Urls in the environmentVariables section of launchSettings.json. In other words:
"profiles": {
"My.Api": {
"commandName": "Project",
"environmentVariables": {
"LogStorageAccountConnectionString": "UseDevelopmentStorage=true",
"ASPNETCORE_ENVIRONMENT": "Development",
"Urls": "https://localhost:7001;http://localhost:7000"
}
}
}
Sadly VS's "Launch Profiles" dialog does not pick up this value nor allow you to set it, but editing launchSettings.json manually isn't too much of a pain.

How to set the environment in a docker with Visual Studio 2019 in ASP.NET Core 3.1?

struggling in Visual Studio 2019 in ASP.NET Core 3.1 (Win10 with Docker Desktop).
I only want to change the "ASPNETCORE_ENVIRONMENT" from "Development" to "Production.
So what I've done was then to edit
launchSettings.json
and edit the environment variables section:
"profiles": {
///cut other
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/version",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production",
},
"publishAllPorts": true,
"useSSL": false
}
}
When I then start debugging in Visual Studio I get: "Unable to configure HTTPS endpoint",
unless it is working fine with "Development".
Nevertheless the container shows in docker inspect still the "Development"
When I then add "ASPNETCORE_URLS": "http://+:80"
the container starts but still shows ASPNETCORE_ENVIRONMENT = Development. Also inside the docker when executing "ENV".
Don't really know, what else I can try.
Hope on your guidance.
Thanks in advance.
Maybe it is a UI Bug, you can check by
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
In my case, the application shows "Production",
but Visual Studio container debug tool shows "Developement".
Besides, you can add a "appsetting.Production.json" to double check the config is changing to Production, hope it helps.
You can find this question helpful: ASPNETCORE_ENVIRONMENT in Docker
The proposed solution there - specify the environment in Dockerfile`s ENTRYPOINT:
ENTRYPOINT ["dotnet", "CoreDocker.dll", "--environment=Production"]

How to define appsetting properties when publishing an asp net core 3.1 app

I have a webapi app made using rider and asp net core 3.1
Under the Properties folder of my project I have a launchSettings.json that seems the place to add all the information to make my app launch the way I like. Here is my launchSettings.json:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": false
},
"profiles": {
"AuthWebApi": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://0.0.0.0:5137"
}
}
}
My problem comes when I want to publish my app. Everything goes well but when I execute my dll with donet, it starts on port 5000 instead of the one I configured in launchSettings.json (5137). I guess this is because the configuration I defined takes effect only in debug. But I'm not sure.
I know I could use the url param when running my binary to make it listen on the port I want but I prefer to have all configuration in the launchsettings.json.
Is this possible? How do you handle your launch settings for a publisher app?
launchSettings.json is used only for development environment:
The launchSettings.json file:
Is only used on the local development machine.
Is not deployed.
contains profile settings.
To set up production/staging environment you can use environment variables and/or configuration files.
There is also an answer for your question here
You can use following command:
dotnet run --urls=http://localhost:5001/

Running multiple apps under same host and port

I am developing multiple asp.net core applications within one solution and when I run the solution in Visual Studio using IIS Express, would like to have them under the same url and port. For example:
App1: https://localhost:44369
App2: https://localhost:44369/App2
App3: https://localhost:44369/App3
I've tried to change the lauchSettings.json file to use the same host and url but then an error comes up that the server can't run.
Is there a way to configure it?
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:44369/App2",
"sslPort": 44369
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"App2": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}
I'm gradually moving a large ASPX app from .Net Framework 4.8 to .Net 5. I ran into a similar problem today. Running two .Net Framework apps together via IIS Express 'just works', but it doesn't necessarily work as easily for .Net Core / 5. I wished to host the legacy portion of the site in the existing web project and root of the website, and I wish to host the .Net 5 portion of the site in a virtual directory under the root. My two sites needed to work together because of claims based auth shared between the two apps, but I was having a heck of a time getting Visual Studio IIS Express integration to work properly and consistently between the two projects. For me, the recipe to getting it working was as follows:
Update both configs for the apps to run on the same host and port but in different directories. One directory may be a parent of the other, or they may be parallel. Both apps must be in the same solution (which is the whole reason we care here, right?). This may entail altering the launchSettings.json and/or the .csproj file, depending on what version of .Net you're using since ports are otherwise assigned randomly by Visual Studio when creating a project, and there isn't a way to change it via the UI. To make sure the hosts and ports are correct after changing them, you can inspect the settings by viewing the project 'Properties' element in Solution Explorer, in the Web or Debug tabs, depending on .Net version.
Make sure there is a web.config file in the root of any .Net 5 / Core web app that is part of the solution. This is key in making sure settings won't get nutty in the applicationHost.config, and this was the part I was missing. The default Visual Studio behavior and default .Net 5 web app templates will result in something like this in the applicationHost.config, and this is the problem when running multiple apps together:
Problematic resulting applicationHost.config snippet:
<aspNetCore processPath="%LAUNCHER_PATH%" stdoutLogEnabled="false" hostingModel="InProcess" startupTimeLimit="3600" requestTimeout="23:00:00" />
The problem here is %LAUNCHER_PATH% isn't consistent, depending on which app you start. To keep config like that from being added to the applicationHost.config, you can add a web.config to the root of each .Net Core/5 app similar to this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<remove name="aspNetCore"/>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="bin\Debug\net5.0\YourExeNameHere.exe" arguments="" stdoutLogEnabled="false" hostingModel="InProcess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_HTTPS_PORT" value="44300" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
Your config may vary. The key here is just to replace %LAUNCHER_PATH% with a path to the exe in the local web.config that IIS Express will pick up no matter how the apps are launched or how the apps are related to one another. You may need to use OutOfProcess hostingModel, and/or you may need to specify some other parameters like the HTTPS port. You may need to adjust the applicationHost.config to clean up any prior mess that may have been left in it. Deleting and letting VS recreate the applicationHost.config may even help.
If you continue to get errors, try stopping IIS Express via your system tray and restart it. In spite of being able to use all the apps at the same time in IIS Express, you still cannot 'View in Browser' for one of the apps while IIS Express is busy serving the solution from the standpoint of the one of the other apps. This also has the unfortunate side effect of locking the output .exe while apps are being served, so killing IIS Express may need to be a regular occurrence to fix build errors. Depending on your particular situation, you may also need to change some other applicationHost.config settings to allow overriding settings in local web.config files. e.g. overrideModeDefault="Allow" and/or lockItem="false".
This is not possible, and is a perfect example of why any would be web developer should familiarize themselves with the actual platform they intend to develop on, namely: The HTTP and TCP/IP protocols, and frankly just how sockets work in general, in this case.
Communication between computers happens over ports via various protocols. That communication happens via packets, which are analogous to a letter sent in the mail. Just as with a letter, the packet is addressed, which allows the receiving computer to route it to the correct destination. When it gets to the ultimate destination computer, that computer must also route it to the application or appliance that it's directed to. This part is analogous to mail delivered to a business. All the mail is delivered to some central part of the organization, where it is then routed to the particular employee it's destined for.
With something like a web application, the "employee" in the above scenario is identified by the URL and/or port. Technically it's always the URL and port, but either can be a "default". So just a port assumes 0.0.0.0 or the set of all IP addresses assigned to the machine, and just a URL assumes the default protocol port (80 for HTTP, 443 for HTTPS). Regardless, there must be one unique recipient for that combination. Again, going back to the office analogy, imagine two employees where sharing and office and a piece of mail was addressed just to the room number of the office. How would you know which of the two employees it was actually destined for? You cannot. In actuality, it's more like two employees with the same first and last name were sharing an office. Even if you had the name of the employee, you still wouldn't know which to deliver it to.
In short, what you're wanting is not possible, and it's obviously not possible if you actually understand the platform you're developing on, which is frankly a prerequisite for any sort of development. Each application must use a unique URL, a unique port, or both. There is no other choice.

Categories

Resources