Connection string from Web.Config not read by ConfigurationManager.ConnectionStrings["Test"].ConnectionString - c#

I have a connection string in my Web.Config file:
<configuration>
<connectionStrings>
<add name="Test" connectionString="MyConnString"/>
</connectionStrings>
</configuration>
And am trying to access it in my code like this:
string connectionString = ConfigurationManager.ConnectionStrings["Test"].ConnectionString;
Why am I receiving this error?
NullReferenceException: Object reference not set to an instance of an
object.
ConfigurationManager.ConnectionStrings["Test"] is NULL but I can't figure out why.
I am using ASP.NET Core 3.1
I installed System.Configuration.Configuration version 6.0.0 using NuGet.
I have the correct using statement at the top of my code file: using System.Configuration;

ASP.NET Core no longer uses the Global.asax and web.config files that
previous versions of ASP.NET utilized.
The web.config file has also been replaced in ASP.NET Core.
Configuration itself can now be configured, as part of the application
startup procedure described in Startup.cs. Configuration can still
utilize XML files, but typically ASP.NET Core projects will place
configuration values in a JSON-formatted file, such as
appsettings.json.
Read the following article: Migrate configuration to ASP.NET Core
So, you can rename the web.config to app.config.
But better solution is to update application to use JSON-formatted file, such as appsettings.json. For more information read the following article: Configuration in ASP.NET Core

Related

Why is web.config getting created on publish not on build the project in Asp.Net Core API?

I have Asp.net Core 3.1 API project. When I build it doesn't create any web.config file, but when I publish the API using VS 2019 in a folder, it creates a web.config file.
So why it's not creating web.config on build ( I think it should not create because there is no web.config file in the project) but why does it create web.config file on publishing?
Edit: I am trying to deploy the application through Octopus, So I copy the bin folder content, and I need the web.config also. So for time being, I have manually created the web.config in the project and then building the project. so it copies the web.config to the bin folder. So Is this the right approach? or is there any way to generate web.config in the bin folder without manually creating it?
As far as I know, the web.config is used to tell IIS about how to use asp.net core module and handler to host the asp.net core application. When you build and test the application in the VS, there is no need to create the web.config, since it will read the launchSettings.json not web.config.
Web.config is a server configuration file, it is used to configures the ASP.NET Core Module.
The web.config file may provide additional IIS configuration settings that control active IIS modules. For information on IIS modules that are capable of processing requests with ASP.NET Core apps, see the IIS modules topic.
Asp.net core web.config content(Without this file, we couldn't directly host the asp.net core application on IIS)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\basket.api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
</aspNetCore>
</system.webServer>
</location>
</configuration>
IIS requires a web.config file for apps that run there.
In ASP.NET Core, web.config is lazy-generated. The assumption (flawed, IMO) is that you don't need web.config until you are ready to publish to IIS. But what if you have your IIS app pointed to your local code instance so that you don't have to republish your app every time you make a code change and want to test it in IIS? Or what if, like OP, you want to use alternate deployment methods?
A workaround in that case is to publish your app once, take the generated web.config, and copy it to the root of your VS project (same level as the bin folder). Subsequent builds will then copy the web.config to bin\debug\net6.0. Still not ideal, but this is better than manually creating web.config and potentially introducing an error in the file.

C# Configuration Manager when executing Unit Test is referencing machine.config rather than app.config

I have read many other post about fixing the issue for NullReferenceException when calling ConfigurationManager.ConnectionStrings as well as what to do when Unit Test is using machine.config rather than app.config but none have worked for me. Below is a list of approaches that I've tried and have been unsuccessful with so far.
Add Existing Item to unit test and reference the app.config for the project you are testing against
Copy the app.config from the targeted project and paste it in the unit test project
Ensure the bin folder of the unit test project is copying the appropriate config file
Set the properties for the unit test to copy to output as always
Below is a copy of my current config within the Unit Test project:
<configuration>
<appSettings>
<add key="Environment" value="Development" />
</appSettings>
<connectionStrings>
<add name="Connection.Development" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDB)\***;Initial Catalog=***;Persist Security Info=True;Integrated Security=True;Pooling=False" />
</connectionStrings>
</configuration>
I am expecting the following line of code to return Connection.Development connection string but instead I get the LocalSqlServer connection string from the machine.config consistently
string connectionString = ConfigurationManager.ConnectionStrings["Connection.Development"].ConnectionString;
I am using VS2017, running .Net Core 2.0, and trying to connect to local MS SQL Db within the application. If someone could tell me how they fixed this problem for their issue it would be greatly appreciated. If you know why, please pass that information along as well.

Solution with pre Core Class Library & .net Core 2 MVC projects - web.config connectionstring not working

I have a solution containing many projects.
One of the projects is a data access layer Class Library. It uses this line for the connection string which it gets from the web.config of any other project that references it:
private string Constr = ConfigurationManager.ConnectionStrings["DefaultConn"].ConnectionString;
I've added a web.config to a .net core 2 MVC app, but I get this error:
FileNotFoundException: Could not load file or assembly
'System.Configuration.ConfigurationManager, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=123456'. The system cannot find the
file specified.
I've also tried adding the connection string to the appsettings.json file - but it also doesn't help; the full contents of appsettings.json:
{
"ConnectionStrings": {
"DefaultConn": "Server=.;Database=MyDatabase;Trusted_Connection=true;"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
}
}
I've found a few articles online dancing around it - but none that can fix this.
How to read web.config file in .Net Core app
This one mentions a similar situation and a nuget package - but it doesn't solve the issue for the user.
How to include reference to assembly in ASP.NET Core project
This one touches on it but applies to Hangfire only, not a Class Library using ConfigurationManager
How can I do this? Thanks.
I realise that ideally you'd use DI and appsettings.json to store a connection string in .net core MVC 2.
However, regarding my specific question - passing a connectionstring to a Class Library that's already expecting something from the web.config - and to aid in transitioning to .net core - this other question was useful:
How to read web.config file in .Net Core app
But no answer answered it - a comment did from Zuhair. Basically just rename web.config app.config and it works. It works for the linked class library too.
Here is my app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=.;Database=mydb;Trusted_Connection=true;" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
You also need to install this NuGet package:
System.Configuration.ConfigurationManager

Why do my IIS site-specific application settings disappear?

I'm hosting an ASP.NET C# website using IIS on Windows Server. I publish to the IIS server using Web Deploy. I have a few application settings that I configure via IIS' site-specific application settings - mostly passwords that I don't want in plain-text in my app.config within the project itself. Every time that I publish, the settings that I've created via IIS disappear. I think the publish is over writing them. I can't figure out how to get them to persist through publishes. Does anybody know how to get the IIS application settings to remain even through Web Deploy publishes?
Not sure if that solves your problem, but you could try something like this:
Every config section has an optional attribute named "configSource" to
point to an external file. Therefore you could break down your web.config
into several files and update them accoringly:
web.config:
...
<configuration>
<appSettings/>
<connectionStrings configSource="connectionStrings.config"/>
<system.web>
...
connectionStrings.config:
<connectionStrings>
<add name="defaultConnectionString" connectionString="..." providerName="System.Data.SqlClient" />
</connectionStrings>
Then you could set the connectionString.config to not be included in the output of the project and just keep it unchanged on the server.
You could also:
-create a new build configuration for deployment
-add a web.config transformation for this build configuration
-deploy using this build configuration
That's how I usually do it

Hiding private details from open source projects

I have a .net github project that is basically a wrapper around a web API. In the test project, I am calling to the API using an API key. I need to keep this key private, how do I accomplish this in a visual studio project?
In some other projects, like python, I can have git ignore the file (config.py) and use something like config.example.py. But in visual studio's case, the project will not compile because of the missing file Config.cs. What is the proper way to solve this? I'm thinking of using this same method of ignoring the file and have them execute a build script that should rename Config.example.cs to Config.cs?
This is the perfect for .config files. Depending on whether its a web or console application, you will have a web.config or app.config file in your project.
You can use the appSettings section to store your API key.
To make things even easier, you can actually have this section read from another file, ie: specialappsettings.config and then just ignore that single file from your repository.
Modify your web.config (or app.config):
<configuration>
<appSettings file="specialappsettings.config">
</appSettings>
<system.web>
<!-- standard web settings go here -->
</system.web>
</configuration>
Create a new specialappsettings.config file:
<appSettings>
<add key="APIKey" value="YourApiKeyValue" />
<add key="AnotherKey" value="AnotherValue" />
</appSettings>
This can be accessed in your code via:
var apiKey = ConfigurationManager.AppSettings["APIKey"];
Notes:
You can keep your settings within the original web.config file as
well but this lets you ignore just the specific settings file from
your git repository without affecting the rest of the project's
necessary configuration details.
The same "key" can be saved in
either file however the external file will override the original
web.config file value.
You are probably looking for the App.config file for a project. It will be copied to <application>.exe.config when you compile it. Users can edit that config file as needed.
In that config file, you can add your API keys:
<configuration>
<appSettings>
<add key="APIKey" value="12345"/>
</appSettings>
</configuration>
Then you can access it from your code using ConfigurationManager.AppSettings:
string apiKey = ConfigurationManager.AppSettings["APIKey"];
One option is to use .config files instead of having secret keys hardcoded in sources.
More info Using Settings in C# and step-by-step guide
<configuration>
<appSettings>
<add key="SecretKey" value="0" />
</appSettings>
</configuration>
var secretKey = ConfigurationManager.AppSettings.Get("SecretKey");
Perhaps you can store the key outside of the Config.cs file and load it at run time.
Bonus, other people using your code won't have to recompile the project to change to their API key.

Categories