web.config best practices when upgrading - c#

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.

Related

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)

Best way to store settings (special requirements)

I found a lot of information for saving different kinds of application/user settings in different places but getting confused what could be the best way for me.
My problem has different dimensions:
The application will have some User-Roles (Admin, StandardUser, ...), where every User (based on Windows-Logon) will belong to one role.
The Admin is allowed to setup everything for everyone.
The settings have different categories:
Application settings (should be the same for every user on the computer)
User-Role-specific settings
User-specific settings
The application has several projects where different projects have to access the settings.
(4. The application is written in C#)
I don't want to mention the things that I have read because I don't want to steer your thoughts into a (maybe wrong) direction.
So, how would you handle this scenario?
Thanks a lot!!
Joerg
EDIT 1
Some more things after the first answers that I hope can clarify my question:
my question doesn't focus on the authentication of the users, it focusses on create/edit/save settings
my first attempts for solving the problem were:
using the Visual Studio Settings.Settings file
... doesn't work because I have several projects that have to have access to the settings AND I couldn't find a way to make the ApplicationSettings writeable (they are readonly)
use the ConfigurationManager-Class
... I am not experienced with this one but as far as I understand this class it is just another class that gives me access to my ApplicationSettings (and has the same problems like #1)
... maybe a link to a good tutorial will help
invent something on my own
... I still hope to find something ready-to-use
I guess in this kind of scenarios you probably have a database. When you incorporate users, user rights, etc in there it is probably also a good place to save your application settings.
I always love the database centric solutions, since there are widely available (when you want to create a new UI based on the same system, you can reuse the settings there).
I think the entity–attribute–value model is a good design strategy to consider.
You can create a view with triggers on them hiding system only properties, enabling the admin to change all, and the user to only change theirs.
By your description I'd say you want Role Based Authentication. It's something that has been asked before. I'd go to the link specified in that answer to find an overview and some code samples of how to approach this problem.
Microsoft has done a great job adding some abstractions with the Membership Providers and now the ASP.NET Identity Framework (in case you have a Web Application). Regardless of what you choose to do, database or config files are going to be involved (take a look here to learn how to manage those) and some sort of claim derived system.
Assumption: You already have figured out how you are going to handle roles, and your question is only about storage/retrieval of settings.
Point #3 means you can't use a Settings file for Application and User scoped settings combined with a custom configuration section for holding the role specific settings (optionally encrypted).
My next suggestion would be a WCF endpoint that exposes the settings, either in their entirety (security trimmed contents of Application + User specific + Role specific) or by some sort of dictionary lookup equivalent. Additionally:
The endpoint would need to require Windows Authentication (or possibly Claims) so that it could determine the user specific/role specific part.
Each application would then need to have knowledge of the WCF endpoint, either through configuration or potentially through WCF Discovery.
Update:
Note that WCF doesn't solve your storage question, but it helps with your point #3 - multiple projects that need to use the same settings. A WCF endpoint allows a single project that encapsulates the storage/retrieval of settings to be re-used by multiple clients. WCF can be complicated to read about, but in practice it's pretty easy to setup - you just decorate an interface and host it in IIS. You could also host it yourself in something like a windows service if you were adverse to using IIS, but deploying it to IIS would be a lot easier. You can then consume it in your other applications by adding a Service Reference to your project, and then you call the interface code as if the code was in your own project.
In case you are talking about a single application with multiple class libraries:
What I'm describing above assumes you are making multiple applications that all need to share settings. If you are actually talking about a single application with multiple class library projects, the built-in Settings can still be used - there is just one manual step you need to do to make it work across projects. After adding settings to both your application project and your class library project(s), you should copy the app.config section containing the settings in your class library and copy/paste it into your application's app.config. Visual Studio isn't very clever and it will only sync the class library Settings changes to an app.config within the class library project, even though an app.config for a class library isn't a "real thing", since only the app.config for the application consuming the class library is actually used by default (which is why you need to merge it into your application's app.config).
If you need multiple class libraries (including the main application project) to use the same settings, you could make a dedicated class library project just to hold the settings (note you can add multiple Settings files to this project to make the settings more modular), and then all the other projects could reference the common settings project (to avoid circular dependencies, you wouldn't hold any Settings in the main application project that a class library needed).
Overriding a user's settings
The Settings object has a mechanism you could use to override settings (say, with value's specified by an administrator). When you add a Settings object to your project, it creates a Settings partial class with some example code for wiring into the SettingsLoaded event. In this event, you could load your administrative settings (either through a WCF call, or perhaps from a know location on the file system) and apply any overrides.

How to use partial config files

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

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

How to conditionally enable actions in C# ASP.NET website

Using a configuration file I want to enable myself to turn on and off things like (third party) logging and using a cache in a C# website. The solution should not be restricted to logging and caching in particular but more general, so I can use it for other things as well.
I have a configuration xml file in which I can assert that logging and caching should be turned on or off (it could also be in the Web.Config, that's not the point right now) which will result in for example a bool logging and a bool caching that are true or false.
The question is about this part:
What I can do is prepend every logging/caching related statement with if (logging) and if (caching).
What is better way of programming this? Is there also a programming term for this kind of problem? Maybe attributes are also a way to go?
Why not just use the web.config and the System.Configuration functionality that already exists?
Your web app is going to parse web.config on every page load anyway, so the overhead involved in having yet another XML config file seems overkill when you can just define your own section on the existing configuration.
I'm curious what kind of logging/caching statements you have? If you have some class that is doing WriteLog or StoreCahce or whatever... why not just put the if(logging) in the WriteLog method. It seems like if you put all of your logging caching related methods into once class and that class knew whether logging/caching was on, then you could save your self a bunch of If statements at each instance.
You could check out the Microsoft Enterprise Library. It features stuff like logging and caching. The logging is made easy by the fact you always include the logging code but the actual logging beneath it is controlled by the settings.
http://msdn.microsoft.com/en-us/library/cc467894.aspx
You can find other cool stuff in the patterns and practices group.
Consult http://msdn.microsoft.com/en-us/library/ms178606.aspx for specifics regarding configuring cache.
I agree with foxxtrot, you want to use the web.config and add in a appsetting or two to hold the values.
Then for the implementation on checking, yes, simply use an if to see if you need to do the action. I highly recommend centralizing your logging classes to prevent duplication of code.
You could use a dependency injection container and have it load different logging and caching objects based on configuration. If you wanted to enable logging, you would specify an active Logging object/provider in config; if you wanted to then disable it, you could have the DI inject a "dummy" logging provider that did not log anything but returned right away.
I would lean toward a simpler design such as the one proposed by #foxxtrot, but runtime swapping out of utility components is one of the things that DI can do for you that is kind of nice.

Categories

Resources