How to get Args from Provider (c# .NET Core console app)? - c#

I try to make a .NET Core console app with singleton. In main I have:
Configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddCommandLine(args)
.Build();
var services = ConfigureServices();
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetService<App>().Run();
and in App.cs:
public App(IConfiguration config, IConfigurationRoot configuration)
{
conf = config;
var list = configuration.Providers.ToList();
var provider = (CommandLineConfigurationProvider)list[1];
}
How can I download string[] (or list, or whatever) with arguments from provider?

Answer provided by Martin Costello (from comments):
You can use Environment.GetCommanLineArgs() to get the raw command line to the application. The providers are an abstraction, so don't give you access to exactly what was passed into them.
Link: learn.microsoft.com: GetCommandLineArgs

Related

'Unable to find an Azure Storage connection string to use for this binding.'

When adding this part of my code to my Startup.cs class
var config = new ConfigurationBuilder()
.AddUserSecrets(Assembly.GetExecutingAssembly(), false)
.Build();
// Make the loaded config available via dependency injection
builder.Services.AddSingleton<IConfiguration>(config);
I got this error System.InvalidOperationException: 'Unable to find an Azure Storage connection string to use for this binding.' in WebJobsServiceCollectionExtensions.cs class i also have AzureWebJobsStorage variable in my local.settings.json.
Define your connection string in local.settings.json.
{
AzureWebJobsStorage={YOURCONNNECTIONSTRINGHERE)
}
Azure Key Vault
In Startup.cs class , add the Json file path
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();

Appsettings transform in .NetCore not working as expected

I have developed a web API and published it on azurewebsites.net.
I have added the following additional appsettings:-
appsettings.Dev.json
appsettings.Test.json
appsettings.Prod.json
To be able to extract values from these appsettings transforms I made the following code changes:
Tried the solution mentioned here:
https://stackoverflow.com/a/44953524/10485667
Even tried using only the Development/Debug, Staging and Production/Release instead of Dev, Test, Prod receptively. But no luck. It would only publish the values from the main appsettings.json.
Startup.cs
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
#if DEBUG
.AddJsonFile($"appsettings.Dev.json", optional: true)
#endif
.AddEnvironmentVariables();
Configuration = builder.Build();
appSettings = Configuration.Get<AppSettingsModel>().AppSettings;
}
even tried this code:
AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
Tried changing the Program.cs:
public class Program
{
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddJsonFile($"appsettings.Development.json", optional: true)
.Build();
ILogger logger = null;
var host = CreateWebHostBuilder(args)
.UseConfiguration(config)
.Build();
logger = host.Services.GetService<ILogger>();
host.Run();
}
}
Tried every possible solution provided on internet but no luck. After publishing to azure, it takes the values only from appsettings.json
I think I might be making some conceptual mistake while attempting these solutions. Any kind of help is appreciated.
Thanks in advance

Setting Azure Functions app's base directory wtih Azure Function app 2.x

I need to set a Azure Functions app's base directory to the azurewebjobsscriptroot like below, but got exception
var config = new ConfigurationBuilder()
.SetBasePath("%HOME%\site\wwwroot") //error
.AddJsonFile("Settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
System.ArgumentException : The path must be absolute. Parameter name:
root at
Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(String
root,ExclusionFilters filters) at
Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath(IConfigurationBuilder
builder,String basePath)
Azure function 2.x
VS 2017
ExecutionContext is null to non-function methods via IoC, alternative to ExecutionContext.FunctionAppDirectory
https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#azurewebjobsscriptroot
You probably want to expand the path first before using it. That way the environment variable(s) embedded in the string can be replaced with the equivalent value of the variable. Resulting in a valid base path for the configuration.
var AzureWebJobsScriptRoot = "%HOME%\site\wwwroot";
var expandedRootPath = Environment.ExpandEnvironmentVariables(AzureWebJobsScriptRoot);
var config = new ConfigurationBuilder()
.SetBasePath(expandedRootPath)
.AddJsonFile("Settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Reference Environment.ExpandEnvironmentVariables(String) Method

ArgumentNullException for ConnectionString When trying to remotely connect to .net core API

First of all is this happening in a Mac and I'm new to dotnet core.
I have installed dockers and setup everything in dotnet core. I did add connectionstring to the 'appsettings' and 'appsettings(Development)'.
"ConnectionStrings": {
"Default": "server=localhost; database=Monitor; User ID=sa; Password=MyComplexpPassword!234;"
},
This is Program.cs file Main method
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
This is startup.cs class ConfigureServices method.
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<MonitorDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddScoped<IUserRepository,UserRepository>();
}
This is a Controller test method to test API.
[HttpGet("getUser")]
public UserResource GetUserInfo()
{
var user_1 = new User();
user_1.FirstName = "MAC";
user_1.LastName = "OS TEST";
user_1.Username = "Apple#gmail.com";
return mapper.Map<User, UserResource>(user_1);
}
This method will perfectly execute If I make a rest call(http) without setting up Program.cs class for remote access.
Now I have set it up to run in 'http://0.0.0.0:6001', So that I can access the API from my phone or from another pc in the same wifi.
I followed This instructions.
Now My Program.cs main method is like this.
public static void Main(string[] args)
{
// CreateWebHostBuilder(args).Build().Run();
var configuration = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
var hostUrl = configuration["hosturl"];
if (string.IsNullOrEmpty(hostUrl))
hostUrl = "http://0.0.0.0:6000";
var host = new WebHostBuilder()
.UseKestrel()
.UseUrls(hostUrl) // <!-- this
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseConfiguration(configuration)
.Build();
host.Run();
}
In terminal I ran this command dotnet run --hosturl http://0.0.0.0:6001
If try to access same method as before this happens.
Notice:- I changed only the host, Because I need to test the API with other devices.
I have other controllers and methods that are connecting to the database and do crud operations with it, Those API calls also face the same issue like this. This only happens if I set it up to remote access.
Notice:- If I change the Startup.cs class Connection string line like this, It will work flawlessly in both configurations.
services.AddDbContext<MonitorDbContext>(options => options.UseSqlServer("server=localhost; database=Monitor; User ID=sa; Password=MyComplexpPassword!234;"));
But I felt that this is not good practice. In future, I have to add JWT Authentication to the API so that APP_Secret also needed to add to the AppSettings.json file.
Thank you.
you didn't tell the application to use appsettings.json. change below configuration
var configuration = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
To
var configuration = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddCommandLine(args)
.Build();
As an alternative, you can use the static WebHost.CreateDefaultBuilder method which by default loads settings from 'appsettings.json', 'appsettings.[EnvironmentName].json', and command line args.
Note -> As stated here:
AddCommandLine has already been called by CreateDefaultBuilder. If you
need to provide app configuration and still be able to override that
configuration with command-line arguments, call the app's additional
providers in ConfigureAppConfiguration and call AddCommandLine last.
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
// Call other providers here and call AddCommandLine last.
config.AddCommandLine(args);
})
.UseStartup<Startup>();

AWS ElasticBeanstalk unable to read appsettings using ASPNETCORE_ENVIRONMENT in ASP.NET Core web app

Background & Attempted Fixes
I am attempting to automate my .NET Core web application deployment using AWS ElasticBeanstalk and configuring each environment with the ASPNETCORE_ENVIRONMENT variable.
I then found out that via numerous (one & two) Stackoverflow questions this is broken in ElasticBeanstalk.
Then following those two SO questions, I tried this in my Startup.cs:
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)
.AddJsonFile(#"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
var ebConfig = ParseEbConfig(Configuration);
builder.AddInMemoryCollection(ebConfig);
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
CurrentEnvironment = env;
}
public IConfigurationRoot Configuration { get; }
public IHostingEnvironment CurrentEnvironment { get; set; }
private static Dictionary<string, string> ParseEbConfig(IConfiguration config)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (IConfigurationSection pair in config.GetSection("iis:env").GetChildren())
{
string[] keypair = pair.Value.Split(new[] { '=' }, 2);
dict.Add(keypair[0], keypair[1]);
}
return dict;
}
and tried accessing the new containerconfiguration values in my HomeController (to test this out) like this: _config.GetSection("ASPNETCORE_ENVIRONMENT").Value; where _config is IConfiguration. This worked when debugging locally & I was able to get the ASPNETCORE_ENVIRONMENT properly. But in Beanstalk it was unable to find that variable.
What seems to be going on
So it appears that Beanstalk is unable to access the containerconfiguration file and it certainly is not able to retrieve the ASPNETCORE_ENVIRONMENT variable, no matter where I set it in my configurations with Beanstalk.
What I am wondering
At the end of the day, I want to be able to set the ASPNETCORE_ENVIRONMENT variable to Dev (for example) in my Beanstalk configuration and have my .NET application load the appropriate appsettings.json file for the environment. I don't necessary need to go the route of the containerconfiguration file, but this seems to be the way it needs to be done.

Categories

Resources