App.config transformation is not working based on environment - c#

I have a console application and I need to separate app.config for diff. env in order to use different connection strings.
I right-clicked on App.config -> Add config transforms and got two files:
App.Debug.config
App.Release.config
Those files are following:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-
Transform">
<connectionStrings>
<add name="SqlCpaConnectionString"
connectionString="blahblah"
providerName="System.Data.SqlClient"/>
<add name="AzureStorageConnectionString"
connectionString="blahblah"
providerName="Microsoft.WindowsAzure.Storage"/>
When getting the settings like:
ConfigurationManager.ConnectionStrings["AzureStorageConnectionString"].ConnectionString
I get null ref ex on both of envs...

See following answer. This will also work with console apps: How do I use Web.Config transform on my connection strings?
Set the connection string transform:
<connectionStrings>
<add name="local" connectionString="Data Source=IPAddress,Port;Initial Catalog=SomeOtherDB;User ID=TopSecretUsername;Password=SecurePassword"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>

Related

In C#, how do i cope with XmlException: 'xdt' is an undeclared prefix. when trying to set new password in connectionString?

I am trying to set a new password in my app.config files. I tried to do this using code below. Exception is thrown here because of the xdt:Transform in the connectionString:
configuration.ConnectionStrings.ConnectionStrings["DbContext"].ConnectionString
= string.Format("Data Source=x ;Initial Catalog=x ;User='sa';Password='{0}';",
textBox1.Text);
Reason: "System.Configuration.ConfigurationErrorsException: ''xdt' is an undeclared prefix. "
This is a transformed config file and hence contains "xdt:Transform"
Here is the connectionstring I want to change:
<connectionStrings>
<add name="DbContext" connectionString="Data Source=x;Initial
Catalog=x;User='sa';Password='x';"
xdt:Transform="Replace" xdt:Locator="Match(name)"/>
</connectionStrings>
Is there any possibility to somehow parse a connectionString part of the xml file? Thank you in advance!
The xdt namespace should be defined. In the a web.release.config file (*), this is done like this:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
in the example below, the "SetAttributes" transform will change the value of a connectionstring
-->
<connectionStrings>
<add name="MyConnectionString" connectionString="some value" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</connectionStrings>
</configuration>
*) I must admit that these transformations are normally used for web.config files rather than app.config files. However, it can be done for app.config also, but this is another topic.

Add new connection in connectionString

I have the next connectionstring file:
<?xml version="1.0"?>
<connectionStrings>
<add name="DefaultConnection"
connectionString="Application Name=CalculatorTest;Server=PC01;Initial catalog=MyDB;Integrated Security=true" />
</connectionStrings>
I want to add a new connection, for example "MyDBTest", staying:
<?xml version="1.0"?>
<connectionStrings>
<add name="DefaultConnection"
connectionString="Application Name=CalculatorTest;Server=PC01;Initial catalog=MyDB;Integrated Security=true" />
<add name="NewDefaultConnection"
connectionString="Application Name=CalculatorTest;Server=PC01;Initial catalog=MyDBTest;Integrated Security=true" />
</connectionStrings>
How do I do it from C# Mvc 5?
Right click on your project and add an Entity Data Object, then enter the name you want it to be called; chose code first from database, then enter the server address and you can also select which tables from the db you want.
This will create the connection string for you. I would however recommend doing this in a separate class library so it’s easier to maintain. Note: if you do use it in a separate class library, you will need to look in the Web.config and copy it over to your main application web.config. Also you will want to add the reference of it in your project references.

Updating a config file adds additional config sections

My goal is to programatically update a .config file belonging to another application.
I start off with a simple config file that looks like this...
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Test1" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
I then run my code to update the connection string named Test1 and rename it to Test2...
var configMap = new ExeConfigurationFileMap() { ExeConfigFilename = #"test\app.config" };
var externalConfiguration = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
externalConfiguration.ConnectionStrings.ConnectionStrings[1].Name = "Test2";
externalConfiguration.Save(ConfigurationSaveMode.Minimal, true);
This saves the configuration file, but now looking at the file you will see some other data has been added to it...
ConfigurationSaveMode.Minimal
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Test2" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<trust level="Full" />
<webControls clientScriptsLocation="/aspnet_client/{0}/{1}/" />
</system.web>
</configuration>
ConfigurationSaveMode.Modified
Using the Modified setting I get even more "stuff"...
<configuration>
<appSettings />
<configProtectedData />
<system.diagnostics />
<system.windows.forms />
<uri />
<connectionStrings>
<add name="Test2" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.net>
<authenticationModules />
<connectionManagement />
<defaultProxy />
...snip...
What is this data and where has it come from? More importantly how can I stop it from being written into my file?
Try changing the ConfigurationSaveMode from
ConfigurationSaveMode.Minimal
to
ConfigurationSaveMode.Modified
Modified only saves the properties that you have changed.
From MSDN:
Full
Causes all properties to be written to the configuration file. This is useful mostly for creating information configuration files or moving configuration values from one machine to another.
Minimal
Causes only properties that differ from inherited values to be written to the configuration file.
Modified
Causes only modified properties to be written to the configuration file, even when the value is the same as the inherited value.
The way I have solved this was to set the Machine Configuration File to be the same as my EXE Configuration file, this way the .net Configuration object does not see that there is any difference between Machine and EXE when it is saving.
For example:
var fm = new ExeConfigurationFileMap();
fm.MachineConfigFilename = fm.ExeConfigFilename = #"C:\dude.config";
var c = ConfigurationManager.OpenMappedExeConfiguration(fm, ConfigurationUserLevel.None);
// Do Stuff
c.Save(ConfigurationSaveMode.Minimal, true);
This way you should not get the section in your config file upon save.

Reading connection string from external config file

I have created a console application and an app.config file and Connections.config file.
The app.config file has a connectionstring property source pointing to the Connections.config
When I tried to read the connection string in the application, I get a ConfigurationErrorException
This is my main method.
static void Main(string[] args)
{
var settings = ConfigurationManager.ConnectionStrings;
if (settings != null)
{
foreach (ConnectionStringSettings setting in settings)
{
Console.WriteLine(setting.ConnectionString);
}
}
}
App.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings configSource="Connections.config"></connectionStrings>
</configuration>
Connections.config file
<?xml version="1.0" encoding="utf-8" ?>
<connectionStrings>
<add name="SQLDBConnecion"
providerName="System.Data.ProviderName"
connectionString="" />
</connectionStrings>
Here I observed two things.
First: If I specify configSource I am unable to read the connection string (throwing exception.)
Second: If I put same connection string in App.config file and tried to read then the code is working but getting two connection string (which supposed to be return only one which is empty string)
The first connection string is sqlexpress connection string like this
data source=.\SQLEXPRESS;Integrated Security=SSPI;
AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
second connection string it returning is empty string (This is expected).
I want to read connection string from external file like in my scenario. How to do that? What am I missing here?
MSDN says:
Do not include any additional elements, sections, or attributes.
You need to remove the XML encoding.
Edit
Also, you need to set the properties of your config file to Copy to Output Directory = Copy if newer or Copy always.
Edit 2
To build on what Dave said, you add the clear element to your external file. Your final Connections.config file should look exactly like this:
<connectionStrings>
<clear/>
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
Your Connections.config file should be as shown below without the xml header
<connectionStrings>
<add name="SQLDBConnecion"
providerName="System.Data.ProviderName"
connectionString="" />
</connectionStrings>
Also for it to correctly locate the file in your console application, please set the Copy to Output Directory to Copy Always or Copy If Newer.
That first connection string you are getting is inherited from the machine.config. This is described in the MSDN documentation. http://msdn.microsoft.com/en-us/library/bf7sd233(v=vs.90).aspx
You can use the Clear tag in your config file to remove inherited connection strings.
http://msdn.microsoft.com/en-us/library/ayb15wz8(v=vs.90).aspx
<connectionStrings>
<clear/>
<add name="SQLDBConnecion"
providerName="System.Data.ProviderName"
connectionString="" />
</connectionStrings>
There is a nice article on MSDN: https://msdn.microsoft.com/en-us/library/ms254494(v=vs.110).aspx.
Quote from the article:
To store connection strings in an external configuration file, create
a separate file that contains only the connectionStrings section. Do
not include any additional elements, sections, or attributes. This
example shows the syntax for an external configuration file.
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
Hope this helps people who run into this question later.

Getting configuration values rom XML file located in the same project

I am making a little program to copy pictures form one location to another. The information for the pictures are stored in a database so I need connections string and also I create a txt file with the final output from the operation and I want to store these two values in a App.Config.xml file.
The structure of my project is very simple :
And the XML files itself is :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyDB" connectionString="Data Source=.\\DVSQLEXPRESS08;Initial Catalog=**;Persist Security Info=True;User ID=**;Password=**;MultipleActiveResultSets=True" />
</connectionStrings>
<createResultFile>
<add key="ResultFile" value="C:\Users\dv\Desktop\Leron\PictureStatus.txt"/>
</createResultFile>
</configuration>
I want to use the connectionString and <createResultFile> value in my PictureTransferTool.cs. This is my first time working with XML file and C# (.NET in general) so I want what is the way to retrieve those config values?
You config file must be like below...
Config File :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ResultFile" value="C:\Users\dv\Desktop\Leron\PictureStatus.txt"/>
</appSettings>
<connectionStrings>
<add name="MyDB" connectionString="Data Source=.\\DVSQLEXPRESS08;Initial Catalog=**;Persist Security Info=True;User ID=**;Password=**;MultipleActiveResultSets=True" />
</connectionStrings>
</configuration>
C# :
You can read Connection String like below
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
Console.WriteLine(connectionString);
You can read User Defined Settings like Below
var Resultfile = System.Configuration.ConfigurationManager.AppSettings["ResultFile"];
Console.WriteLine(Resultfile);
The Way I normally do user-defined parameters in my app.config is i put them in the appSettings tab.
<appSettings>
<add key="myStr" value="String Value" />
and then you can access it with
string myStr = System.Configuration.ConfigurationSettings.AppSettings["myStr"];
It works for me.
Linq;
using System.Xml.XPath;
...
var doc = XDocument.Load("test.xml");// You should put the way to your XML
var name = doc.XPathSelectElements("/configuration/connectionStrings/add").Value;
var name = doc.XPathSelectElements("/configuration/createResultFile/add").Value;

Categories