I am trying to write my connection string in my appsettings.json file and bring it into my startup file but I keep getting a Value cannot be null.
Parameter name: connectionString. I have been using various examples but can't seem to see this new setup with ASP.NET 1.0 Core startup class.
Appsetting.json file:
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Data Source=server;Initial Catalog=dbase;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
}
Method attempting
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
var connStr = Configuration.GetConnectionString("DefaultConnection");
System.Console.WriteLine(connStr);
services.AddDbContext<DbContext>(options => options.UseSqlServer(connStr)); //error right here -- Null value
}
First of all, the
"Data": {
"ConnectionStrings": {
"DefaultConnection": "Data Source=server;Initial Catalog=dbase;Trusted_Connection=True;MultipleActiveResultSets=true"},
}
Is slightly different from the structure you get when you add a "Asp.NET Configuration File" in Visual Studio. When you do that you get
"ConnectionStrings": {
"DefaultConnection": "Data Source=server;Initial Catalog=dbase;Trusted_Connection=True;MultipleActiveResultSets=true"},
without the "Data" JavaScript Object. So that's why the extension method isn't working. It expects this structure. You can use this structure (the one with "Data") anyway and get your connection string like so:
var connectionString = Configuration["Data:ConnectionStrings:DefaultConnection"];
Notice that you are navigating through the JavaScript object tree using : instead of .. That's due to some cross-platform issues with using the ..
If you edit out the "Data":{} you can do this :
var connectionString = Configuration["ConnectionStrings:DefaultConnection"];
Now the extension method will work. Underneath the Microsoft extensions it is the same thing as the code above.
var config2 = Configuration.GetConnectionString("DefaultConnection");
I was missing the letter 's' after the ConnectionString property name in the appsettings.json when using Configuration.GetConnectionString("name")
If you want to copy
"ConnectionStrings ": {
"SpyStore": "Server=(localdb)\\mssqllocaldb;Database=SpyStore;Trusted_Connection=True;MultipleActiveResultSets=true;"
}
The method wording GetConnectionString confused me, I hovered over it and oh be hold it was looking for ConnectionStrings property name instead of ConnectionString
DefaultConnection is the inner object in the json structure and it is the child of Data object.
So if you want to be exact with your config file you can use
var connStr = Configuration.GetSection("Data")
.GetSection("DefaultConnection")["ConnectionString"];
I got this because I had a connection string with a \ in it, which needed escaping to be a \\. So my localdb connection string was causing a load error like this:
"DefaultConnection": "Server=(localdb)\myinstance;Integrated Security=true;Initial Catlog=my-localdb;"
and was fixed by making it:
"DefaultConnection": "Server=(localdb)\\myinstance;Integrated Security=true;Initial Catlog=my-localdb;"
this is was the message that appeared me
Value cannot be null.
Parameter name: connectionString
I fix it changed in the startup these lines
services.AddDbContext<AppIdentityDbContext>(options =>
options.UseSqlServer(
Configuration["Data:BookStoreContext:ConnectionString"]));
To
services.AddDbContext<AppIdentityDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("BookStoreContext")));
I had got similar error.My "appsettings.json" file was not loading because the properties of the file was Copy to Output Directory -> Do not Copy. I set that to Copy always save and rebuild.It worked.
in asp.net core you must add IConfiguration to startUp contractor method and assignee this Parameter to a property inherited from IConfiguration inside class
public class Startup
{
public Startup(IConfiguration configuration)
{
this.Configuration = configuration;
}
public IConfiguration Configuration { get; }
my issue is fixed by fixing a typo
I experienced this problem using asp.net core 3.0.
The workaround fix for me is:
Instead of:
var connectionString =
Configuration["ConnectionStrings:DefaultConnection"];
Use this:
var connectionString =
Configuration["ConnectionStrings::DefaultConnection"];
The emphasis here is the double colon in the connection configuration.
Another mistake in my case was that I was using ConnectionString, instead ConnectionStrings (Note last 's')
Maybe you can try this:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer("DefaultConnection")
);
Then set your appsettings.json do something like this:
"ConnectionStrings:": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HOME1_DATABASE;Trusted_Connection=True;MultipleActiveResultSets=true"
},
After that, when a I add migration via the console, it succeeds.
While using Postgres SQL the appsettings.Development.json must contain
"ConnectionStrings": {
"DefaultConnection": "User ID=user;Password=xxxx;Host=127.0.0.1;Port=5432;Database=abc;Pooling=true"
}
Content in the Startup.cs file would be like
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>
(p => p.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")));
}
The correct way to add connection strings into your appsetting.json file is the following:
"ConnectionStrings":{
"DefaultConnection":"Server=localdb)\\MSSQLLocalDB;Datbase=MyShop;Trusted_Connection=true"
}
I get it,it was because the name of connection string that in app settings was difference from that in the configuration that in Startup !!!
The right code of connection String Configuration in startup
// replace NAMEHERE with the name of the class that inherits from DbContext
services.AddDbContextPool <NAMEHERE> (opts => opts.UseSqlServer(Configuration.GetConnectionString("here put the same Connection string name that in appsettings")));
I fought with the null connection string issue far too long, only to find I was doing this:
builder.Services.AddDbContext<MlDataContext>(provider => new MlDataContext(config.GetConnectionString("ConnectionStrings:SqlConnectionString")));
I was using both the ConnectionStrings: prefix AND GetConnectionString. When I removed the prefix it worked:
builder.Services.AddDbContext<MlDataContext>(options => options.UseSqlServer(config.GetConnectionString("SqlConnectionString")));
For Postgre Db, Below worked for me
private readonly IConfiguration _config;
string connectionString;
public DataBaseContext(IConfiguration config)
{
_config = config;
connectionString= _config.GetValue<string>("ConnectionStrings:sampleConnection");
}
Config file:
"ConnectionStrings": {
"sampleConnection":".."
}
Start up file:
services.AddScoped();
In my case I had two IConfiguration definitions in my Startup class. Not helpful :)
I had this error on the day when usin Asp.Net Core 5. I tried all above solutions with no satisfaction. Then I deleted the "ConnectionStrings" section the appsettings.json file and launched a migration. After the error, I rewrote the section and launched again the migration. All worked fine.
Please make sure you have all you connection strings defined in the app.json.
My problem was I had two different projects that added a dbContext in their services config
The identity project which made a reference to the identityDb
The persistence project that all my data access logic
I solved the issue by having both connection strings defined in the app.json
try it, it will work for you on version 3.0.0.
public class Startup
{
private readonly IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.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.AddControllersWithViews();
services.AddDbContext<DataContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("MyPortfolio"));
});
}
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MyPortfolio": "Data Source=(localdbd)\MSSQLLocalDB; initail catalog=MyPortfolioDB; Integrated Security=true"
}
}
I had the same problem and this fixed it for me:
connStr = Configuration.GetConnectionString("DefaultConnection");
change to:
connStr = Configuration["DefaultConnection:ConnectionString"]
I am having the same error but realize to be an typo.
"ConnectionStringd": {
"DefaultConnection": "Server=localhost;Database=BookListRazor;Trusted_Connection=True;MutipleActiveResultSets=True"
},
the correct typing should be
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=BookListRazor;Trusted_Connection=True;MutipleActiveResultSets=True"
},
Remove this line from YourProjectName.csproj file:
<Nullable>enable</Nullable>
In my case this is a new deployment to a new server. It turns out the environment variable ASPNETCORE_ENVIRONMENT was not set, so .NET Core couldn't get the connection string from appsettings.PROD file, and thus passed null to options.UseSqlServer(connection).
Once I created a new environment variable ASPNETCORE_ENVIRONMENT and set its value to PROD, problem is solved.
instead of using the method given below
builder.Services.AddDbContext<FullstackAPIcontext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("FullStackConnectionString")));
You can directly add the connection string after Usesqlserver .The code snippet is given below
builder.Services.AddDbContext<FullstackAPIcontext>(options =>
{
options.UseSqlServer("Server=myserver;Database=FullstackDb;Trusted_Connection=SSPI;Encrypt=false;TrustServerCertificate=true");
});
You need to change your appsetting.jsonto:
{
"Data": {
"ConnectionStrings": {
"DefaultConnection": "Data Source=server;Initial Catalog=dbase;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
}
And now will be working:
var connStr = Configuration.GetConnectionString("DefaultConnection");
Related
I'm writing my first Azure function (based on .NET Core 2.x), and I'm struggling to extend the app settings with my custom mapping table.
I have a file local.settings.json, and I have tried to extend it with a "custom" config section that contains a few "key/value" pairs - something like this:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
... (standard config settings) ...
},
... (more default sections, like "Host" and "ConnectionStrings")
"MappingTable" : {
"01" : "Value1",
"02" : "Value2",
"03" : "Value3",
"else" : "Value4"
}
}
I get the IConfiguration injected into my worker class via constructor injection, and it works just fine for the "basic" default values stored in the "Values" section:
public MyWorker(IConfiguration config)
{
_config = config;
string runtime = _config["FUNCTIONS_WORKER_RUNTIME"]; // works just fine
// this also works fine - the "customSection" object is filled
var customSection = _config.GetSection("MappingTable");
// but now this doesn't return any values
var children = customSection.GetChildren();
// and trying to access like this also only returns "null"
var mapping = customSection["01"];
}
I'm stuck here - all the blog post and articles I find seem to indicate to do just this - but in my case, this just doesn't seem to work. What am I missing here? I'm quite familiar with the full .NET framework config system - but this here is new to me and doesn't really make a whole lot of sense just yet......
I have also tried to move the entire MappingTable section to appSettings.json - but that didn't change anything, I'm still getting back only null when trying to access my custom config section's values....
Thanks!
Update: all the suggested ways of doing this work just fine with a standard ASP.NET Core 2.1 web app - but in the Azure function, it's not working. Seems like code in an Azure Function is treating configuration differently than a regular .NET Core code base ...
I did something similar using .net core 3.0
local.settings.json
{
"AppSettings":{
"MappingTable" : {
"01" : "Value1"
}
}
}
Reading appsettings:
private void AppSettings()
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
var 01 = config["AppSettings:MappingTable:01"];
}
In the Azure portal, you need to add this as an application setting.
In your Function App -> Configuration -Application Settings -> New Application setting
Name:AppSettings:MappingTable:01
Value:Value1
A R G H ! ! !
I knew it - such a stupid little mistake - but with rather massive consequences.....
In my startup class, I had this code (plus some more):
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
var config = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
.....
}
}
but what was missing is this one line of code after the call to .Build() above:
builder.Services.AddSingleton<IConfiguration>(config);
Somehow, the settings in the Values section of local.settings.json were present and accessible, but any custom config sections weren't.
Adding this one line has solved my problem - now I can easily read the MappingTable from my local.settings.json (or appsettings.json) file and use it in my code.
I'm trying to create an azure durable function but it's very difficult to find some normal guides on this subject. I've setup the DI and I try to read the settings of the function but it crashes
I have setup an Azure Function project in VS 2019 and added a Durable Orchestrator Function Template. I removed all the "static" references from the class and all seem to work fine until I add the configurationbuilder in the startup file
Can anyone explain to me how this should work or give some guidance, where to find some explanation of the configuration of a durable functions ? What should I have in the host.json , local.settings.json and how this changes be when I publish it on the portal ?
My case is this. The startup file looks like this
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
[assembly: FunctionsStartup(typeof(DurableFunctions.Startup))]
namespace DurableFunctions
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var settings = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
}
}
}
The host.json is like this
{
"version": "2.0"
}
The local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
And the error I get when I start the debugger is this
This is output:
[11/8/2019 10:29:04 AM] A host error has occurred during startup operation '8b80bc94-2b98-408b-895f-c5697430acfd'.
[11/8/2019 10:29:04 AM] Microsoft.Azure.WebJobs.Extensions.DurableTask: Value cannot be null.
[11/8/2019 10:29:04 AM] Parameter name: hostConfiguration.
Value cannot be null.
Parameter name: provider
You want to instead override the ConfigureAppConfiguration method in your FunctionStartup class (https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources).
The following example takes the one provided in the documentation a step further by adding user secrets.
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
FunctionsHostBuilderContext context = builder.GetContext();
builder.ConfigurationBuilder
.SetBasePath(context.ApplicationRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{context.EnvironmentName}.json", optional: true, reloadOnChange: false)
.AddUserSecrets(Assembly.GetExecutingAssembly(), true, true)
.AddEnvironmentVariables();
}
By default, configuration files such as appsettings.json are not automatically copied to the Azure Function output folder. Be sure to review the documentation (https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources) for modifications to your .csproj file. Also note that due to the way the method appends the existing providers it is necessary to always end with .AddEnvironmentVariables().
A deeper discussion on configuration in an Azure Function can be found at Using ConfigurationBuilder in FunctionsStartup
Did you get a response to this?
Did you try adding the local settings from the json, before the Environment Variables?
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
// This gives you access to your application settings in your local development environment
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: false)
.AddJsonFile("secret.settings.json", optional: true, reloadOnChange: false)
// This is what actually gets you the application settings in Azure
.AddEnvironmentVariables()
.Build();
I am having trouble when I deploy, I have set up a variable group yet they are not being picked up.
I have an appsettings.json file with the following values
{
"MailOptions":
{
"Username": "ruskin",
"Password": "password"
}
}
When I read it via the ConfigurationBuilder I can only access the values via configuration["MailSettings:Username"]. I want to grab the entire MailOptions string, is there anyway to do that? I don't want to use Json to parse the file etc...I want to stick to configuration builder.
I would expect configuration.GetSection("MailOptions") to work? It simply returns null.
What I have tried
SomeSection aSection = new SomeSection();
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.Configure<SomeSection>(options => configuration.GetSection("SomeSection").Bind(aSection));
var someSection = serviceCollection.BuildServiceProvider().GetService<IOptions<SomeSection>>();
// aSection is instantiated but no values in it
// someSection is null
My appsettings.json
{
"SomeSection": {
"UserName": "ruskin",
"Password": "dantra"
}
}
And my POCO class
public class SomeSection
{
public string UserName { get; set; }
public string Password { get; set; }
}
The configuration framework is an abstraction over the underlying source types. So MailOptions:Username could come from JSON, an environment variables or even INI files - and the configuration system can even be configured with multiple sources. If need a JSON string to configure your mail library and want to use the configuration abstraction, I suggest creating a class to hold the settings and serialize it to a JSON string again.
EDIT:
Using configuration.GetSection("SomeSection").Get<SomeSection>() I can successfully get the POCO from the app. see sample application.
We are in the process of re-writing one of our applications using ASP.NET Core. The architecture we're trying for has a Web API running on a different URL from the presentation. The root URL for this API will change in different environments, of course, so I'm trying to figure out how I can set up configuration and access to the Web API root URL in the JavaScript that requires it for retrieving data. For example, say I have an AJAX call to fetch some data from the API:
$.ajax({
dataType: "json",
url: "http://this.url.will.change/api/whatever", //this will change!
success: function(response) {
//load the items
}
});
I've set up appsettings.json files for various build/deploy scenarios and have them reading and injecting nicely, so I can store the URL there.
{
"Data": {
"DefaultConnection": {
"ConnectionString": "whatever"
}
},
"AppSettings": {
"ApiRootUrl": "http://apiroot/api/"
}
}
I considered writing a UrlHelper extension to provide the Web API root, but I don't think there's a way to inject the IOptions object into a static extension method. So, my question is really this: How can I make a configuration setting globally available in my CSHTML and JavaScript?
Update your Startup.cs like below
public class Startup {
public IConfigurationRoot Configuration { get; set; }
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv) {
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(appEnv.ApplicationBasePath)
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(_ => Configuration);
}
}
Then on your controller you can inject configuration like this
public class ConfigurationController : Controller {
private readonly IConfigurationRoot config;
public ConfigurationController (IConfigurationRoot config) {
this.config = config;
}
public string Test() {
return config.Get<string>("AppSettings:ApiRootUrl");
}
}
We've used to create a special configuration controller which was responsible for creating a dynamic javascript file from selected configurations settings. You can inject IOptions to the controller. Then from the options you can construct a new custom configuration object which will hold only the properties you want to expose (you probably don't want to expose anything like connection string to your db).
Use a json library (like json.net) to serialize this custom configuration object to a JSON string and create file content out of it like
string fileContent = "var globalConf =" + JsonConvert.SerializeObject(configObject);
Convert the string to array of bytes and return it as FileContentResult.
We were also setting some cache headers so the browser didn't hit the controller each time and used cache.
Of course you need to setup routing o the call to specific URL will hit your controller and return the javascript file you have dynamically created. You can reference it on a website using usual script tag.
As for the server side rendering you can always include IOptions in the model (or create a new model which will wrap both options and the original model)
I want to load all settings key value pair from json file at once and use the settings key value in mvc 6 view page where required.I would be grateful if best solution is provided.I have a scenerio as below
if(Settings.enable_logo_text)
{
<span>Settings.logo_text</span>
}
The official documentation regarding the new configuration and options is quite good, I would recommend having a look there first.
Following the guidance provided there, start by creating a POCO class for your settings:
public class Settings
{
public string logo_text { get; set; }
public bool enable_logo_text { get; set; }
}
Update the ConfigureServices method of your startup class so you read your settings from the configured Configuration and is then available as a service that can be injected wherever you need to:
public void ConfigureServices(IServiceCollection services)
{
...
services.Configure<Settings>(Configuration);
services.AddOptions();
}
If you want to use a the appsettings.json file, make sure you also build your Configuration object including that json file. For example:
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}
This way you can configure your values in the appsettings.json file and the values will be set on your Settings class:
{
...
"enable_logo_text": true,
"logo_text": "My Logo Text"
}
Finally, you can access the configured values by adding a IOptions<Settings> dependency. The most straightforward way would be to directly inject the options into the view (as explained in the docs), but you might want to consider injecting the options into the controller and passing them to the view in a more controlled way:
#inject IOptions<Settings> Settings
...
#if(Settings.Value.enable_logo_text)
{
<span>#Settings.Value.logo_text</span>
}