How to add transformed web.$configuration.config files to project - c#

I have a web service project where I have one main web.config file and then different environment specific files as well like web.Staging.config/web.QE.config etc. Now, I am following this: http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx to add a prebuild event to my project to copy the configuration specific config file to the main web.config file but the problem is, it copies it without transforming and hence resulting into something like below:
<add key="somekey" value="Development" xdt:Transform="Replace" xdt:Locator="Match(key)"/>
My question is, is there a way to keep the transformed config files ready to be copied while building the project?

You can use SlowCheetah to do the transform for you.This work with multiple environment QA, UAT etc. This also has provided as nuget package
https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.SlowCheetah-XMLTransforms
Recent new feature in 2017 15.8.4 has feature for managing secret. Its worth to have a look
https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Managing-User-Secrets/?utm_source=vs_developer_news&utm_medium=referral

Related

ASP.Net - use seperate configuration file for database and app settings

I have an asp.net project that is using Entity Framework that is used on several different client servers. This means a different web.config for each for connectionstrings and app settings.
Hasn't been an issue but I changed something that altered the web.config file recently and I manually had to adjust this for each client, I also have to exclude the web.config file in updates to ensure their own one is not overwritten.
What I would like to achieve is store these settings in maybe another config file that the project can pick up and use. Maybe that on Globals Application_Start gets these and imports them/overwrites the current web.config file perhaps.
Essentially I don't want to affect the current code that uses the connection string and ConfigurationManager.AppSettings used throughout the project but I do want to be able to let the web.config file update for each client and use a seperate file for some settings.
NOTE: I do not have access to publish directly to each server so I can't simply write a different deploy web.config for each one. I have to publish the files locally, store as zip and automated routine on servers downloads and extracts accordingly.
EDIT:
Please do say if this is considered a bad idea but an idea I had was to put something similar in Global.asax Application_Start method:
Does config file exist?
If no, create file and append all current settings in web.config
If yes, open and import those settings to the current web.config overwriting the original values
Hopefully then in a few weeks time, after I have asked all clients to perform a manual update they will have this code and I can begin to include the web.config in updates.
In VS, inside the Build menu, the last item is Configuration Manager.
In here you can specify various different release environments which can each have their own web.config transforms.
This is normally used for production/staging/test environments. However, I can see no reason why you could not use this and have a configuration file for each of your servers/environments.
You will then need to create the transformations for each environment, by rightclicking the web.config, then selecting Add Config Transform.
each of the environments you had setup can then override the settings in the main web.config. (That now acts as a template/default settings)
e.g.
In Web.EnvironmentA.Config
<add key="ConnectionString" value="ConStringA" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
In Web.EnvironmentB.Config
<add key="ConnectionString" value="ConStringB" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
Then when you do a publish, you simply setup which config file to use. If you use Azure or the VS publish method, it will save each of these settings, so then you can simply push to the relevant environment easily.
Just make sure you test this works as you intent first, before you start publishing everywhere ;)

What is App.config in C#.NET? How to use it?

I have done a project in C#.NET where my database file is an Excel workbook. Since the location of the connection string is hard coded in my coding, there is no problem for installing it in my system, but for other systems there is.
Is there a way to prompt the user to set a path once after the setup of the application is completed?
The answers I got was "Use App.Config"... can anyone tell what is this App.config and how to use it in my context here?
At its simplest, the app.config is an XML file with many predefined configuration sections available and support for custom configuration sections. A "configuration section" is a snippet of XML with a schema meant to store some type of information.
Overview (MSDN)
Connection String Configuration (MSDN)
Settings can be configured using built-in configuration sections such as connectionStrings or appSettings. You can add your own custom configuration sections; this is an advanced topic, but very powerful for building strongly-typed configuration files.
Web applications typically have a web.config, while Windows GUI/service applications have an app.config file.
Application-level config files inherit settings from global configuration files like machine.config. Web also applications inherit settings from applicationHost.config.
Reading from the App.Config
Connection strings have a predefined schema that you can use. Note that this small snippet is actually a valid app.config (or web.config) file:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="MyKey"
connectionString="Data Source=localhost;Initial Catalog=ABC;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
Once you have defined your app.config, you can read it in code using the ConfigurationManager class. Don't be intimidated by the verbose MSDN examples; it's actually quite simple.
string connectionString = ConfigurationManager.ConnectionStrings["MyKey"].ConnectionString;
Writing to the App.Config
Frequently changing the *.config files is usually not a good idea, but it sounds like you only want to perform one-time setup.
See: Change connection string & reload app.config at run time which describes how to update the connectionStrings section of the *.config file at runtime.
Note that ideally you would perform such configuration changes from a simple installer.
Location of the App.Config at Runtime
Q: Suppose I manually change some <value> in app.config, save it and then close it. Now when I go to my bin folder and launch the .exe file from here, why doesn't it reflect the applied changes?
A: When you compile an application, its app.config is copied to the bin directory1 with a name that matches your exe. For example, if your exe was named "test.exe", there should be a ("text.exe.config" in .net framework) or ("text.dll.config" in .net core) in your bin directory. You can change the configuration without a recompile, but you will need to edit the config file that was created at compile time, not the original app.config.
1: Note that web.config files are not moved, but instead stay in the same location at compile and deployment time. One exception to this is when a web.config is transformed.
.NET Core
New configuration options were introduced with .NET Core and continue with the unified .NET (version 5+). The way that *.config files works hasn't fundamentally changed, but developers are free to choose new, more flexible configuration paradigms.
As with .NET Framework configuration .NET Core can get quite complex, but implementation can be as simple as a few lines of configuration with a few lines of c# to read it.
Configuration in ASP.NET Core
Configuration in .NET Core
Simply, App.config is an XML based file format that holds the Application Level Configurations.
Example:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="key" value="test" />
</appSettings>
</configuration>
You can access the configurations by using ConfigurationManager as shown in the piece of code snippet below:
var value = System.Configuration.ConfigurationManager.AppSettings["key"];
// value is now "test"
Note: ConfigurationSettings is obsolete method to retrieve configuration information.
var value = System.Configuration.ConfigurationSettings.AppSettings["key"];
App.Config is an XML file that is used as a configuration file for your application. In other words, you store inside it any setting that you may want to change without having to change code (and recompiling). It is often used to store connection strings.
See this MSDN article on how to do that.
Just to add something I was missing from all the answers - even if it seems to be silly and obvious as soon as you know:
The file has to be named "App.config" or "app.config" and can be located in your project at the same level as e.g. Program.cs.
I do not know if other locations are possible, other names (like application.conf, as suggested in the ODP.net documentation) did not work for me.
PS. I started with Visual Studio Code and created a new project with "dotnet new". No configuration file is created in this case, I am sure there are other cases.
PPS. You may need to add a nuget package to be able to read the config file, in case of .NET CORE it would be "dotnet add package System.Configuration.ConfigurationManager --version 4.5.0"
You can access keys in the App.Config using:
ConfigurationSettings.AppSettings["KeyName"]
Take alook at this Thread
Just adding one more point
Using app.config some how you can control application access, you want apply particular change to entire application use app config file and you can access the settings like below
ConfigurationSettings.AppSettings["Key"]
Application settings enable you to store application information dynamically. Settings allow you to store information on the client computer that shouldn't be included in the application code (for example a connection string), user preferences, and other information you need at runtime.
To add an application configuration file to a C# project:
In Solution Explorer, right-click the project node, and then select Add > New Item.
The Add New Item dialog box appears.
Expand Installed > Visual C# Items.
In the middle pane, select the Application Configuration File template.
Select the Add button.
A file named App.config is added to your project.
take a look at this article

.NET .config HELL

I have the following projects:
MVC
Console application
Class library
Windows forms application
COM Library
All these applications need to use a single configuration file. As far as I understand, app.config files are for windows, console applications and class libraries when web.config are for the web projects.
The same configuration need to be accessible in all of these projects. I have read that it's suggested to use machine configuration file, but we won't always have access to that, therefore configuration files must reside within our solution.
I don't fully understand how the configuration files get build. Currently I wrote a simple project where I have the following:
Class library to store for serving configuration files. A have attempted to do this through reflection.
Windows application that should read the app.config from a class library.
When I execute the following code I expect to get a configuration file with test values:
_applicationSettings = ConfigurationManager.OpenExeConfiguration(
System.Reflection.Assembly.GetAssembly(typeof(WCSConfiguration)).Location
).AppSettings;
What I get instead is an empty application settings file.
Class library has the following App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="TestTextKey" value="TestTextValue"/>
</appSettings>
</configuration>
I have tried using .GetExecutingAssembly() method which I expect to return an assembly of a code that's currently being executed. This didn't work, instead it has returned the assembly of a Windows application.
GetAssembly(type(WCSConfiguration)) has returned a right assembly, however, the configuration file was missing in the bin/debug directory.
I have a feeling that either I'm doing something fundamentally wrong or Microsoft hasn't made this flexible enough. I have also tried to search MSDN for explanation, but this hasn't been documented well IMO.
I have also left COM in bold because I'm not sure whether any config files would be available to COM library at all. Firstly I would like to get other projects to work.
I understand that this is a lot of information. Any help would be greately appreciated. Previously we have chosen to use registry, but this has turned out to be nasty, mainly because access to registry is not available in some scenarios. Additionally we now have multiple versions of the applications and switching between branches is a half an hour job :(
Thank you
Edit:
If I add the dll's config sections to app.config that means that these settings will be available only from that application. Please correct me if I'm wrong. Example that I have provided is a scaled down version. In total there are about ten windows applications, a single MVC project and range of class libraries all of which need to make a use of that configuration.
Configuration settings are mostly connection strings, lookup values that do not belong in the database and few other minor settings. Main concern at this point are the connection strings. There are few minor releases of the application where each release points to a different database.
What I'd like to get out of this is a good workable solution so that it can be posted online and other people who come across the same problem won't spend days of their time.
Morale of the story IMO:
Use both App.config and Web.config to store location of your own configuration file.
Write simple XML serializer to read/write config and DLL for serving the configuration.
COM objects are a long story and were implemented with a "hack", since neither App.config or Web.config are available in COM DLLs.
Note ConfigurationManager.OpenExeConfiguration needs to be passed the filename of the config file, not the executable.
You'll need to append .config to the path of the executable. To get the exe assembly use Assembly.GetEntryAssembly.
If you have configuration settings you want to share across multiple pieces of code that are not all in the same .NET Process, I would suggest:
Put them in their own myStuff.config.
In .NET code use ConfigurationManager.OpenExeConfiguration to open and access myStuff.config.
Non-.NET code will need to use an XML parser to load and read the settings. Unless you configuration structures are very complex this shouldn't be too hard to encapsulate.
Put the path to myStuff.config in the app.config of each application sharing this configuration for .NET applications. (Not non-.NET applications: depends on what works for that application.)
Another approach, where the configuration structure is the same but the settings are per-application would be a custom configuration section.
A couple of general points -- add the dll's config sections to the app.config file rather than relying on the dll's config file to get picked up; and app.config actually gets renamed to .exe.config on build, so you need to make sure a file of that name's available.
Also -- you're not constrained to using the default config loading mechanism to configure your application. You could create your own configuration classes and just use XML serialization to deserialize and configure at will.

Solution wide app.config / web.config?

I have a solution with one asp.net-mvc-2 project, one web service, one class library and three normal desktop apps. Currently I need to copy all app.config settings from one project to the other. That is a nightmare if I want to change something.
I know there is a solution to store all these information in the global .config files, but I am looking for a solution to store the values dedicated to my solution not to my machine. Is that possible?
You can add a single .config file to one of your projects, and then choose Add -> Existing Item... -> Add As Link to add a reference to that file to your other projects. They will all build with the file as if it was their own copy, but there will really only be one copy, and you will only have to make changes in a single place.
I have found a really simple solution here:
1. Create a file CommonSettings.config In your Common, Class library project.
2. Put your common setting in this file:
<appSettings>
<add key="someCommonSetting" value="some value"></add>
<!-- more setting here -->
</appSettings>
Note: <appSetting> has to be the root element in your CommonSettings.config (don't put it under <configuration>)
3. Make sure CommonSettings.config file is copied to output directory:
4. In all other project's App.Config/Web.config files, add the above common settings
That's it... You common settings will be included in every other config file.
<appSettings file="CommonSettings.config">
<add key="Value1" value="123" />
</appSettings>
Note:
For this approach to work, the shared config file should be copied to
the project’s output directory so it is adjacent to the regular
App/Web.config file. Add the existing shared .config file to the
project as a Linked file and set it to ‘Copy if newer’. You should see
something similar to this in your .csproj file:
<None Include="..\CommonConnectionStrings.config">
<Link>CommonConnectionStrings.config</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
You can do the same for ConnectionString, copy all your connection strings in CommonConnectionStrings.config, and in other App.Config/Web.Config, reference it like this:
<connectionStrings configSource="CommonConnectionStrings.config" />
Note: If you are using this solution for connectionStrings, you cannot have a project specific connection string, all of the connection strings will be copied from the common config.
Assuming you could have a path where both your website and webservice could access it, then you could potentially use the appsettings " file " attribute to have the settings stored in one common place.
Refer http://www.codeproject.com/KB/dotnet/appsettings_fileattribute.aspx
Hope this helps!
I would comment on the answer #Sahuagin gave, but I don't have enough reputation. This does work with App.config files, but you have to add a text file, then call it App.config. After that just declare the XML (as seen below)
<configuration>
<!-- add you values or whatever here-->
</configuration>
Then do as #Sahuagin said and add it as a link to your solution. It works a treat.

C# can we have multiple .config file for a project?

If we can have more than one .config files, we can share one config file with other projects and put private configuration into another. Visual Studio 2008 will be confused?
No, except for the <appSettings> node which has a special file= attribute which works in a "cummulative" manner, all configuration sections are single shot affairs - you have it, and you have one of it exactly - or you have nothing.
<appSettings file="common.appsettings.config">
<add key="private1" value="value1" />
</appSettings>
This will read in the contents of the common.appsettings.config file and anything that's not being overwritten by an explicit value in your own config here is being used from that external config file.
You cannot add additional "private" info to an existing configuration section, as far as I know.
Visual Studio 2010 has support for multiple .config files. It is one feature of new web application packaging and deployment system. We can create now separate web.config files for each configuration we have for application. But for 2008 there are no support for multi config files, you can workaround this by adding two config files and rename them in build time
Example:
private.config
public.config
on pre-msbuild event merge these two files
rename merged file, it should be web.config or app.config
Hope this helps...
s
You can have multiple web config for each directory although only one config section handler.
The configuration files are hierarchical from general to specific. Configuration files further down in the hierarchy override any settings from the previous ones. So if you have a solution that includes a master web.config file, any web.config files in your projects override it and are specific and visible only to those projects. If a project is comprised of several folders, you can add a web.config file to each of those as well, again with different settings that also override any of those set above. But I caution over-engineering this or you may have difficulty with a trickle-down of certain property values or loopholes in security if it is security that you are configuring at each level.
Each config section can be put in an external file, and referenced from the main app.config / web.config via the configSource attribute. However, you will have to write custom section handlers for each custom section / external config file that you want to write, which may get a little tedious. In addition, the appSettings section can be externalised and referenced via the same mechanism.

Categories

Resources