How to use partial config files - c#

I am involved in a project where development and testing is going on in different locations. There are a few entries in the app.config that are "local" to the different locations (hence, "config"). Therefore, everyone tends to keep his own app.config, which always makes it difficult for a new setting to be introduced.
I'm looking for an idea, something like partial classes, where the bulk of an app.config can be in one place, and a few items in another, and yet all wind up in the proper exe.config after a build.

First of all you can split up config file using the configSource attribute. For example, in web.config you could write:
<authentication configSource="ConfigFiles\authentication.config" />
.. and have your authentication config in another file. This may be of use to you, with local variations (eg. DB settings).
Secondly, and more importantly, you probably want to watch this video to learn about deploying to different environments (using web.debug.config and web.release.config)
http://www.hanselman.com/blog/WebDeploymentMadeAwesomeIfYoureUsingXCopyYoureDoingItWrong.aspx

Related

Are strings in web.config compiled into the executable?

The storage admins where I work have bought and configured a new huge NAS system.
Over time all current storage will migrate over there. This means that various network paths will change and this will break some in-house applications. We are reviewing a bunch of old apps the find the ones that use current paths like: \\old-file-system.company.com\Users so that we can modify them.
The old apps I have found all set these paths as strings in the project web.config file. My question is: are these paths compiled into the executable or are they read at runtime from this config file? Can we just modify the paths in the config files and not have to potentially rebuild them or upgrade them to newer .Net versions?
Cheers
The values are read from the config file.
That is precisely the point of config files: to provide the ability to alter these values without needing to redeploy the application.
Note that this may need you to restart the app pool on IIS after making changes. Usually, it should automatically do that when it detects changes to the config file, but from historical experience this sometimes breaks without you noticing.
As an aside: don't forget about alternative config storage methods such as databases.
yes, they are!
it will then depend on the code.
So, As a general rule no.
However, if you added new config items, then they may well not show up.
And if the code used the built in class in place of often used configuration manager to get values?
then you have to re-compile.
But, we also might use this:
vb.net:
Dim rstData As New DataTable
Using cmdSQL As New SqlCommand(strSQL, New SqlConnection(My.Settings.TEST3))
cmdSQL.Connection.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
So, in place of config manager, I often use My.Settings.TEST3.
(you get intel-sense). So on build, a class is created for some of those web config files.)
In c#, the above is:
Properties.Settings.Default.TEST3
And again often used due to intel-sense in place of configuration manager.
That class is re-build at compile time. So, if the code used to get web.config values is always configuration manager, then you would/should be ok.
However, if code used the built-in class like above?
The values ARE pulled from web.config at compile (build) time.
the class is called
c#
Settings.Desinger.Cs
vb.net
Settings.Desinger.vb
So, I would check the above two files. That class tends to come from here:
Now the above when we add say a connection string to the project?
The above DOES update and put the above settings into web.config.
However, the class created (settings.Desing.cs/vb?
It is re-generated each time, and it DOES COPY the values from web.config.
So this means that after changing the settings in that project, you REALLY do have to re-build.
As noted, if one came from desktop land, then we just add settings to above, and use them. They actually are created in web config, but we often use the above - since as noted ANY new setting we add to the project now has intel-sense.
So, I would search the source code for:
vb:
My.Settings.TEST3
(search for My.Settings.)
or
c#
Properties.Settings.Default.TEST3
(search for Properties.Settings.)
if either of above are used in the code?
Then yes, you have to re-build since they are re-created at compile time into a class, and the values ARE pulled from web.config at compile time.
If configuration manager was used in all cases, then you are ok.
however, if the designer class was used, then a re-build is required, and worse a change in web.config will not be reflected in that class until a re-build.

One Web.config in ASP.NET MVC instead of multiple for each Views folder

My ASP.NET MVC web application has 5 areas. Each area has its own Views folder with it's own Web.config in it. That makes 6 configuration files together with the main Web.config at the application root. It makes it a bit difficult to manage.
As far as I know, these configs make two things (at least by default):
1.) Setup the Razor host factory to include selected namespaces by default.
2.) Block direct access to the files in the Views folder by handling the requests with a HttpNotFoundHandler.
The code in all of those Web.config files is almost identical for me and it doesn't seem to me like a good way to manage these configurations. If I added more areas or organized my code more granularly, I could end up with more that just 5 Web.config files. Why would I need so many? Isn't one enough?
My thoughts on the points are following:
ad 1.) Cannot all of these namespaces be imported either once in the application root Web.config file instead or imported in a _ViewStart.cshtml file?
ad 2.) Wouldn't it make more sense to block access to all code files in all folders and then use the opposite approach -- i.e. change the folders with static files in them (like Assets folder) to use StaticFileHandler? In principle, it seems like a more secure approach to me to whitelist the files that are allowed be read by StaticFileHandler rather than to specify which files should be handled by HttpNotFoundHandler.
Is this doable? Am I missing something? Has anybody else encountered similar issues with having too many Views Web.config files?
Thanks for answers.
Just place a single web.config file inside the Areas folder and remove the individual web.config files from each of the 5 areas.
Configuration files in ASP.NET operate on a principle of inheritance. MSDN article - ASP.NET Configuration File Hierarchy and Inheritance

How to use environment dependent app.config file

We are a group of C#/.NET 4.5 developers working on the same application.
The application has a set of configurations related to each developer machine, like the connection string to the DB, network related settings (proxies, IPs, credentials) and a LOT MORE.
Because the application has grown we are incurring in a lot of environment related configurations like for example:
If this is MyPC then load the connection string for my PC.
If this is the XDeveloperPC then specify proxy’s settings.
Also if new developers leaves or join the group, then the process to update the file becomes a total head ache. Maintaining the file has become very hard and is a possible source of bug and errors.
I was thinking in having specific app.config files related to each developer environment like:
app_MyPC.config
app_XDeveloperPC.config
And when the application builds or executes then specify which one to load as if it where the default app.config of the application. Then, when the application or any class or method refers to a given configuration (like the connection string) is access to this configuration file as if it where accessing to the app.config default file.
I would not want to create a Configuration class that builds immediately when the application starts because then I should have references from every place to this class and the application is quite large, with a bunch of projects and dlls.
I rather prefer to hear some opinions and what do you think should be the best way to achieve this.
Is it possible to achieve this?
How?
Do you know a better approach?
FYI, please note that .NET only loads one config file for the whole application. You could try multiple config files something as like specified here,
Multiple App.Config Files in .NET Class library project
Hope this helps...
You can specify sections of app.config to be loaded from another file. See this answer
However, you might have to customize the above solution, the app.config files and the way configs are organized.
Another approach is to use a custom settings file instead of app.config. This will need some code change to use the config file. This config can either be an XML or a JSON file (JSON is easy to deal with). You can use an inheritance model wherein generic settings come from one file, specific settings come from another file and so on. Also, you can load settings from such file at runtime and change application behavior on the fly.
If you decide to use custom config file, and if you already have lot of code written considering App.config file, you can abstract the app.config calls to a method and let that method deal with where to pull the settings value from. That way you can minimize the code change and keep everything tidy.
Maybe you can use the machine.config file (C:\Windows\Microsoft.NET\Framework\your Framework version\Config\machine.config)

web.config best practices when upgrading

I send out an app and I let customers make changes to connection strings and such in the web.config.
When I upgrade my app this causes an annoyance because I don't want to overwrite their values with mine.
This is especially bad when versions of .net are upgraded.
How do people typically handle this type of situation?
For example do they somehow split the web.config out so the customer data is no longer part of it?
I've never heard of anyone making web.config accessible and writable to customers or any other business folk. You're just asking for trouble.
It sounds like you may want to develop a small front-end (web) utility to allow them to submit values in a form and save to a database. Then have your application access the database for these values, and not the web.config.
This seems to be more of a content management issue.
Split your configuration file into two. One for you and the other for your customers.
All configurations that are customizable by your customers go into the customer config file and everything else goes into yours.
This will let you easily upgrade/modify your config file without overwriting your customers'.
You can use the SectionInformation.ConfigSource element to declare associated configuration files. This blog post shows you how you can do it.
I even used it in this project to detect changes to external configurations in ASP.NET.
There are a few ways to handle this. I'll mention two. One concerns your delivery process. The other actually involves the web.config.
1) Don't ship the web.config as "code". Consider it "configuration". This doesn't apply well to all scenarios (in fact, a customer based scenario is the bad scenario I was thinking of). If you are delivering to "production" you can agree to make them responsible for the contents of web.config (and a good practice there is to try and refactor as much as you can to machine.config). That way, things like the connection string become production concerns and not development concerns.
2) Use the configSource attribute. ASP.NET 2.0 supports externalizing attributes with the configSource attribute. It can be hard to turn over ALL of the web.config as a "production concern" (in a delivery to customer scenario, They may not be experts in all of this).
So you externalize it like this. Here is your current appSettings section, for example:
<appSettings>
<add key="EnableFrobbing" value="false" />
<add key="ExpectFooingFrom" value="fooingserver#domain.com " />
</appSettings>
If these are settings you want to externalize so your new shipments don't override customer settings, replace it with this:
<appSettings configSource="App_Data\WebConfigXML\appSettings.xml"/>
Relative paths only here as far as I know.
References:
(Shows the property is new in ASP.NET 2.0)
http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource%28v=VS.80%29.aspx
http://www.codeproject.com/KB/aspnet/Manage_Webconfig.aspx
http://trycatchfail.com/blog/post/2008/09/25/Webconfig-magic-configSource-and-file-attributes.aspx
You have a couple options. The best, IMO, would be to not publish web configs when you push the app to their environment. If a new configuration section/setting needs to be written, you can either encapsulate some logic to programmatically write the new config in a little helper app and run that as a post-deployment action, or you can just paste the new settings into an e-mail and send to someone you trust on the other end to put it in the configs. I would recommend against the second option in 99% of cases; there is a lot of potential for crossing wires or just being ignored, then it's your fault when the system goes down because the configs didn't make it in.

c# pattern for two applications sharing a configuration file

I have two applications that have many common configuration properties. When a configuration property of one changes, I want the other to change as well. Does anyone have a sensible way to accomplish this before I start off down the wrong track?
EDIT: I'm using .NET 2.0
You can create and reference a common configSource for the configuration section(s) involved. For instance, if you wanted a common set of AppSettings, copy your current appSettings to a new file (say appSettings.shared.config) and replace them in both app configs with this:
<appSettings configSource="appSettings.shared.config"/>
Here's more documentation: http://sunali.com/2008/01/23/configsource-property-dividing-configuration-files-into-pieces/
Far as I know, this cannot be done for an entire file, only sections, and each section will need its own file (and the section must still be declared in the configurationsections element of the app.config). But, this has a number of really cool uses; for instance, you can separate your connection strings into files geared towards different environments (local, development, testing, staging, production) and by changing one filename in one place you've now pointed your app at the different environment.
One easy way to accomplish this is to use the configSource attribute in the app.config in both applications, and point this to a common file. Bingo, change one file, all apps are updated.
Check the MSDN documentation on it here.
there are a couple of different ways you could do this:
use the registry
use a config file in a common location
use a configuration table in a database

Categories

Resources