I am trying to retrieve values from my App.config file which is stored in my working directory, however when I run the program it returns null. I am very confused why this is so, and have looked over the code many times in an attempt to spot an error.
Here is my App.config file code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="provider" value="System.Data.SqlClient" />
</appSettings>
<connectionStrings>
<add name="connection" connectionString="Data Source=(local)\SQLEXPRESS;Initial Catalog=Autos;Integrated Security=True;Pooling=False" />
</connectionStrings>
</configuration>
Here is my C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data;
using System.Data.Common;
namespace DataProviderFun
{
class Program
{
static void Main(string[] args)
{
string p = ConfigurationManager.AppSettings["provider"];
string c = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
...
When I run this code, p = null and c = null.
I have referenced System.Configuration.dll.
Did you ensure that the config file is placed correctly at the directory from which you're running the application? Is there actually a file called <app name>.exe.config in that directory?
I'm just guessing here - maybe you added the App.Config file in a different project then your exe assembly project...?
By the way, I copied your code and App.Config as is to a clean project, and this code worked for me. So I'd look in the direction of the config file itself and not in the code. The code is fine...
Hope this helps,
Ran
If your config file use in different class library you must change your name YourClasslibraryDllname.dll.config and you must change config file copy to output directory property
Ex:
YourSolution
ClassLibrary_1
ClassLibrary_1.dll.config
ApplicationConfigurationReader.cs
ConfigurationConst.cs
ClassLibrary_2
ConsoleApp
Rename your config file like this YourClasslibraryDllname.dll.config
Open Properties Window
Change Do Not Copy to Copy Always
Add reference -> Assembly -> System.Configuration
Add below clases in ClassLibrary_1 Project
ConfigurationConst Class using System.Configuration;
public static class ConfigurationConst
{
public static KeyValueConfigurationCollection Configs;
}
ApplicationConfigurationReader class using System.Configuration;
internal class ApplicationConfigurationReader
{
public void Read()
{
// read assembly
var ExecAppPath = this.GetType().Assembly.Location;
// Get all app settings in config file
ConfigurationConst.Configs = ConfigurationManager.OpenExeConfiguration(ExecAppPath).AppSettings.Settings;
}
}
Read Config using ClassLibrary_1;
static void Main(string[] args)
{
new ApplicationConfigurationReader().Read();
var Configval = ConfigurationConst.Configs["provider"].Value;
Console.ReadKey();
}
i Hope you can get clean help
In Case all the settings are correct but still if you get null values, Please check your app.config file and replace the xml code as below,
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
</configuration>
Now Run your Code, you might see the proper values
If you have .dll in your debug folder, then rename your confif file to yourprojectname.dll.config. This worked in my case
Related
I have reduced this to the simplest possible.
VS2019 MSTest Test Project (.NET Core) template
Default unit test project .
Use nuget to install System.Configuration.ConfigurationManager(5.0.0)
Add app.config file to project (add -> new Item -> select Application Configuration File>
Add entry to config file.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="TestKey" value="testvalue"/>
</appSettings>
</configuration>
Debug the code below and k is null.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Configuration;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var k = System.Configuration.ConfigurationManager.AppSettings["TestKey"];
}
}
How do you get the unit test to read the config file?
If you add this line to your TestMethod, it will tell you what is the name of the config file it is expecting to use:
public void TestMethod1()
{
string path = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
var k = ConfigurationManager.AppSettings["TestKey"];
}
When I ran it, it called the file "(path-to)\testhost.dll.config", not "App.config". So all I did was rename the file to "testhost.dll.config", change its Build Action to "Content" and "Copy always", ran the unit test, and it gave me the right value in var k.
I can't explain why it would look specifically for that filename, but for some reason it is.
You have to tell the configuration manager what file to load. Don't rely on the file matching the exe name, etc. Just keep the name as app.config.
System.Configuration.ConfigurationFileMap configMap = new ConfigurationFileMap("./app.config");
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(configMap);
string value = configuration.AppSettings["TestKeyā€¯];
I'm using the Simple.Data ORM to hook up a database from within the Visual Studio environment that's defined in a local sql file (named convertcsv.sql). I'm following the instructions detailed here, and thus far, I've installed Simple.Data.SqlServer and Simple.Data.Ado via NuGet, have the following in my App XML file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings>
<add name="Simple.Data.Properties.Settings.DefaultConnectionString"
connectionString="convertcsv" />
</connectionStrings>
I have the following in my Program.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Simple.Data;
namespace DatabaseWalkthrough{
class Program{
static void Main(string[] args){
var db = Database.Open();
var tmp = db.mytable.FindAll(db.mytable.NC == 505);
foreach (var d in tmp){
Console.WriteLine(d.NC);
Console.ReadKey();
}
}
}
}
NOTE: In the convertcsv.sql file, there is only one table (mytable) and NC is one of its well-defined fields containing integral values.
At the line where the foreach loop is initialized, the debugger alerts the following error:
Additional information: Format of the initialization string does not conform to specification starting at index 0.
A little bit of sleuthing reveals this Stack Overflow question a similar problem, but that particular instance of the error appears to have been caused by improper credentials to access a database on a server, whereas I'm trying to propagate a database into my C# app in Visual Studio to update it.
I have the following hypotheses for why this could be an issue:
1) The App config XML file cannot locate the convertcsv.sql file. Somewhat unlikely since I preemptively added this file into all of the project subdirectories.
2) Missing parameters - this is possible since I've seen some variation for how DB connections are arranged in the App config file, but the Simple.Data documentation is somewhat translucent.
Any other ideas?
I want to understand a proper way of handling the scenario below
I have C# Solution which has two projects
One project is HelloWorld
and another project is TestHelloWorld
HelloWorld project read the config using ConfigurationManager.AppSettings["Message"].ToString()
And TestHelloWorld project is the NUnit project to test the HelloWorld project.
When the job being run from NUnit, the code of reading config is not working. Because it tried to read config from TestHelloWorld.config instead of HelloWorld.exe.config.
Can someone please provide some good practice of handling this.
I attached a graphic of my source code and also put the code below, appreciate people if you can download the code and have a try.
Thanks
Program.cs code as below
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
WordToSay wts = new WordToSay();
Console.WriteLine(wts.WordText());
Console.ReadLine();
}
}
public class WordToSay
{
public string WordText()
{
return ConfigurationManager.AppSettings["Message"].ToString();
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings >
<add key ="Message" value ="Hello"/>
</appSettings>
</configuration>
Class1.cs code as below
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using HelloWorld ;
namespace TestHelloWorld
{
[TestFixture]
public class Class1
{
[Test]
public void TestHello()
{
WordToSay wts = new WordToSay();
StringAssert.AreEqualIgnoringCase("Hello", wts.WordText ());
}
}
}
If your unit tests are designed to test the code, then don't depend on the config file at all. Extract your dependency out of your classes and use dependency injection to inject the data in. That way, you can stub your configuration class.
Alternatively, just add an app.config file to your unit testing project that contains the relevant information.
EDIT:
You can also look over this post Reload app.config with nunit
I have NUnit test (version 2.6.4) test. It uses ConfigurationManager.AppSettings["foo"] to retrive a configuration setting from the app.config file (which is in the test project). This is my App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="bar.config">
<add key="thisSettingIsVisible" value="yes, indeed"/>
</appSettings>
</configuration>
and this is bar.config file:
<appSettings>
<add key="foo" value="this setting isn't visible"/>
</appSettings>
I'm using ReSharper 10 test runner to execute the test. bar.config file is copied to the bin/Debug directory. In fact, that configuration was working some time ago, but stopped. Any clues what can be wrong?
Now, I've figured out a workaround, but I'm not happy with this solution:
private static void InitializeAppSettings()
{
var exeAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyName = exeAssembly.GetName().Name + ".dll";
var testDllFolder = new Uri(System.IO.Path.GetDirectoryName(exeAssembly.CodeBase)).LocalPath;
var openExeConfiguration = ConfigurationManager.OpenExeConfiguration(Path.Combine(testDllFolder, assemblyName));
foreach (var setting in openExeConfiguration.AppSettings.Settings.AllKeys)
{
ConfigurationManager.AppSettings[setting] = openExeConfiguration.AppSettings.Settings[setting].Value;
}
}
BTW. I can't abstract away ConfigurationManager usage form existing, legacy code.
I replicated your use case and found that my additional config worked in the context of an ASP.NET site but the additional appSetting was null in a test project until I changed the Copy to Output Directory property to Copy Always
If you use R# 10.0.0 or R# 10.0.1 - it is a known issue for such builds and it has been fixed in R# 10.0.2 build.
Using Visual Studio 2012 which was recently installed but now I can't connect to our SQL Server database.
These are the steps I'm following
create App1.config
type this in App1.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name ="xxx" connectionString="USER ID=xx;PASSWORD=xx;PERSIST SECURITY INFO=True;Data Source=xx;Initial Catalog=xx" />
</connectionStrings>
</configuration>
Add a reference to the project to System.Configuration
Create access to namespaces via:
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
implement the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
namespace ConsoleApplication10 {
class Program {
static void Main(string[] args) {
SqlConnection conn = null;
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["xxx"].ConnectionString);
}
}
}
I've created a new console app and added the above and I still get an error NullReferenceException was unhandled Object reference not set to an instance of an object. ...
EDIT
Via the immediate window I determined that the following is null:
ConfigurationManager.ConnectionStrings["xxx"].ConnectionString
If I hard-code the connection string into the constructor for SqlConnection then it connects ok
What am I missing - something really obvious!! Or is this in connection with my new VS ?
check what is in the ConfigurationManager.ConnectionStrings by excecuting at least the following:
if (ConfigurationManager.ConnectionStrings != null ) {
Console.WriteLine(ConfigurationManager.ConnectionStrings.Count);
Console.WriteLine(ConfigurationManager.ConnectionStrings[0].ConnectionString);
Console.WriteLine(ConfigurationManager.ConnectionStrings[0].Name);
....
} else {
Console.WriteLine("null");
}
This will highlight any obvious problems like duplication of the App.config file which could well be the case as you mentioned App1.config in the OP.
Check your output folder.
Assuming your application is called myapp.exe, there should be myapp.exe.config.
This should exist, and should contain the contents of your app.config file in Visual Studio.
If it doesn't, check whether you already have an app.config file elsewhere (I notice you called your file app1.config)
Have your tried checking what the value of ConfigurationManager.ConnectionStrings["xxx"].ConnectionString is and hardcoding with that value? Do you still get null?
Also it's advised to created the connection like this:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["xxx"].ConnectionString))
{
//code
}
I would reply but I don't have enough rep yet ... :-(
Guessing from the fact that your code does not "do anything" with conn yet, I'm pretty sure that the ConfigurationManager returns null for the connection string name you pass in. An exception is thrown by the SqlConnection's constructor when passing in null instead of a valid connection string.
When you place your connection strings in Properties->Settings, as a connection string, access them with full namespace, and your done.
See my answer here