Anything wrong with putting connection strings in applicationSettings? [duplicate] - c#

This question already has answers here:
Pros and cons of AppSettings vs applicationSettings (.NET app.config / Web.config)
(6 answers)
Closed 7 years ago.
.NET has supported a number of ways to store configuration settings for quite some time, which has led to a good deal of confusion. It doesn't help that the top three hits for a search for "Settings in C#" over on MSDN are ten years old (and many of the related questions [2] on this venerable site are also 6-7 years old). It is really hard to determine which of the early recommendations have since been deprecated.
In my project I have chosen to use ApplicationSettings (as opposed to AppSettings) because:
That appears to be the current recommended approach on MSDN (and here).
The AppSettings element appears to be deprecated as of .NET 4+* (topic is "no longer available"; but see "Other Versions" on that page.) [*Although, confusingly, the AppSettings Property is still supported]
I prefer to edit the settings in a designer tool, rather than an xml editor.
I prefer strongly typed settings.
However, now I need to decide where to put my connection strings. The most current documentation on MSDN (and here on SO, as well as CP) still appears to recommend using the <connectionStrings> section of the app.config. But accessing this from the code requires the use of the old syntax, which I now consider obsolete along with appSettings. In other words, it makes no sense to read one part of the app.config file with the old syntax:
ConfigurationManager.ConnectionStrings["MydDBConnName"];
and another part of the same file with the new syntax:
Properties.Settings.Default.myOtherSetting;
Plus, it prevents me from being able to edit the strings in the designer.
So bottom line: is there any reason not to standardize all my configuration settings (including the connection strings) in the ApplicationSettings element?

The ConnectionStrings section allows you to not only define the connection string in the config, but also lets you choose the provider, so you code can (theoretically) use any subclass of DbConnection, DbCommand, etc.
In reality, however, supporting that kind of flexibility means you have to use SQL statements that are provider-agnostic (meaning you can't do things like date math that do not have a standard SQL syntax), and require more "plumbing" code to create the right types of objects. You can see some examples here.
If you only support one database provider (SQL Server, Oracle, ODBC, OleDB) then there's no real benefit to using ConnectionStrings over a string application setting.

I suggest that you keep your classes settings-source agnostic.
For example if you have a DatabaseContext that requires a connection string, then inject that primitive dependency in the constructor. Do not locate the connection string directly via ApplicationSettings.
Locating primitive dependencies (e.g. settings) from your classes is exactly the same as using the Service Locator anti-pattern.
The only location in your application that should acquire settings (e.g. connection strings) is the Composition Root. So you can obtain settings from ApplicationSettings here and inject them into your classes.
This allows you to change your mind later if you want to use a different way for storing/retrieving settings.

As you must have read on the pages that you linked to, the main benefit of using <connectionStrings> is that it provides mechanisms for encrypting the strings in order not to keep passwords in clear text. If you use Windows authentication to connect to the database then I guess you don't need it and really doesn't matter where you keep your connection strings. It's just a standard way of doing this.
I believe, however, that you are mistaken saying that the 'old syntax' is deprecated. For example, <appSettings> is still documented, it just changed the address. It would bring havoc if it was. It's not my area, but I think what you refer to as the 'new syntax' is the way of accessing settings in a desktop application, you don't have it in server-side applications.

I believe the ApplicationSettings element is just used for organization. If you notice in Entity Framework or most other database connections, they store them in the config under the ConnectionStrings element. The only thing I would worry about is storing any sort of sensitive data such as connection user and password. A common way to get around that is to allow the Windows Authentication to handle the connection.

A standard is what you make. For example in my current work environment the only information that changes in a particular application is the server name. We have dev/test/prod servers. Therefore we only store the SQL Server name in the configuration file. The database name doesn't change. We just read the database server from the configuration file and build the string in the application.

Related

Application Settings in MVC5 Web App - Using C# class vs Web.Config?

I'm building out my application and I'm at a point where I've hardcoded a lot of settings at the top of my class files - stuff like ApiSid and ApiKey, SmtpServiceUsername, MyEmailPassword etc. I'm now trying to consolidate these and I see two options:
1) Push them all into web.config. I don't like the thought of muddling up my web.config with tens (almost 100) settings though... I also feel uncomfortable with security here.
2) Build a static class that just contains these settings (Settings.cs) - basically housing a bunch of constants that are referenced throughout the app.
I feel more comfortable with the second approach because I can keep my settings totally isolated and not worry about exposing them via web.config - is there anything inherently wrong with this approach?
is there anything inherently wrong with this approach?
What makes you think putting constants in the code is any more secure than in the config? The compiled DLLs are right there next to the Web.Config, if somebody can examine one of them they can examine the other one. Hard-coded values can be de-compiled pretty easily.
Config files exist for a reason. Specifically, if any value is going to change per environment then it belongs in the config file. That way the same identical codebase can be used in any environment (development, test, production, etc.) and you'd just edit the config values for that environment. Having to re-compile the code just to deploy the same version to a new environment is less than ideal, since it's no longer the same version.
I don't like the thought of muddling up my web.config with tens (almost 100) settings though
Why not? If they're all flat static values, a list of appSettings keys would be fine. If there's more structure to them, create custom config sections.
This is not necessarily the best approach but I'd store these kind of settings in the database. This gives you database security for the settings plus it's easy to update the settings without having to stop / restart the application so you avoid kicking out users.
Once you have your settings in the database, you can load them periodically (like every 15-20 minutes) to detect changes. In the meantime, create a dictionary of the data and either wrap it in a class that provides type-safe access through properties or just use the dictionary directly. Since this is web application, you'll have to use a thread-safe class (like ConcurrentDictionary) to make sure multiple threads can safely access your settings.
If you have so many settings, web.config would be cluttered and every change would force an app pool restart. As #David mentions in his answer, the config file gives you an easy way to have different settings for different environments but this is also easy to do with a database approach where settings may be present once per environment.

Initialise BasicHttpBinding object from file other than app.config?

I currently have code, in C#, that requires a BasicHttpBinding object to connect to SSRS. As it stands, I initialise this object using values assigned in code, rather than reading it from the app.config (this is because the platform I'm deploying to, MS CRM 2011, does not provide access to the app.config file for reading. In fact, I don't think the app.config file even gets copied to the server).
I'd like to make this binding editable without recompiling so the solution can be installed easily at different customers. The cleanest way I can think of is to have the binding config stored in a web-resource (for non-CRM people, this is just a name for a file stored inside CRM that you can access from code), but I'm not sure of the best way to parse that config into a BasicHttpBinding object? Manually parsing it and setting the properties seems inefficient and not very robust.
Is there any way of getting .NET to to it for me (similar to the BasicHttpBinding(string) constructor, but since I don't have access to app.config this isn't an option)?
Given the (presumably) low volatility of this configuration, could you not store it in the plug-in secure / unsecure configuration in your plug-in registration step? Accessing this at runtime would be significantly quicker that connecting to CRM to retrieve the contents of a web resource. Granted, it means that you require the plug-in registration tool and a sys admin to make changes but it also means that any sensitive data is obfuscated from users. App.config for a plug-in is indeed unavailable - but then that's what your config section in the plug-in step are for.
As far as using the constructor for BasicHttpBinding
It sounds like you're looking for a way have all of the constructor magic done for you by just passing the key name for a config section. I don't believe that this will be possible but in any case your suggestion that "Manually parsing it and setting the properties seems inefficient" is probably unfounded - after all that's exactly what the native constructor will ultimately be doing anyway. Hide it behind a function and you'll never know it's there ;)
I have connected to the SSRS web service in plugins previously (beware - not supported in CRM Online due to service not being exposed :( ) and I took my usual approach of storing config, as above, in the plugin configuration and then read it into an XmlDocument at runtime then parsed out the values as required to instantiate objects/set properties.
So long as the config is the same for all requests to the plugin, you can also potentially afford some efficiencies by setting the config values (not the connection itself) as class-level properties in your plugin (even though this is against advise in the SDK - but that's due to thread-safety which shouldn't be an issue with "static" config values such as this) and only read the values from config if they are not already set.

Where do I put a configuration when using windows services, webservices and websites?

Problem:
I'm developing in ASP .NET with C# and I want to validate e-mails.
For that I'm using a regular expression (let's call it EmailRegularExpressionValidator) and my problem is where schould I put the regex to easily change them if I want/need to with no need to recompile the code.
The validation is made in "IntermediateServices", in business layer, where all the things come to do theirs things.
Solution 1: web.config
I have lots of windows services and wich one have theirs own config. If I put EmailRegularExpressionValidator in that I have to write in all and when I change one I have to change all. Not good.
Solution 2: DB
Sometimes, I have to validate 1000 mails (or even even more), and if I put EmailRegularExpressionValidator in database I have to do 1000 querys to know EmailRegularExpressionValidator value. I think put it in memory but I have webservices. Not a good idea soo.
Solution 3: Resources
Resources can only be easily changed if in website. When I put them in business layer I cannot change them easily.
Solution 4: BD + Session
Like I say after, I'm using webservices....
Hope I was been explicit and hope you can help me.
Sorry about my english (greetings from Portugal).
Thanks a lot.
In your case i would recommend config files.
.NET configuration files have an hierarchy, and it all starts in the machine.config, and all .NET applications read settings from that config.
If you don't override the keys on the applications config files, the application will use the settings from the machine.config. It is the most central point and can be used for all applications, change once, it changes for all.
It can be found here:
C:\Windows\Microsoft.NET\Framework\
Then after that depends on the framework you are using,
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG
or here:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config
Example:
Just place this after the <configuration> tag in the machine.config.
<appSettings><add key="myParameter" value="myValue"/></appSettings>
then in your code,
Configuration con = ConfigurationManager.OpenMachineConfiguration();
ConfigurationSection consec = con.Sections["myParameter"];
You must add a reference to System.Configuration
Hope it helps.
I used a smarter way...
Instead edit machine.config as suggested I simply use cache who do the magic I want!
You can find a good article about how you can use it here: http://codemaverick.blogspot.pt/2007/01/caching-in-windows-application-i-was_8639.html

Holding ConnectionString in app.config or properties.Resources of a C# project?

I've saved my project connection string in app.config file and use it without any problem.
But some one told me that she has put it in Properties.Resources of her project.
Now, my question is is there any preference between these two ways? or what else do you offer?
Thank you
It's better to put it in app.Config if you want to be able to change this post-deployment. If you only need it to be configurable at compile time, either option is fine. Compile-time only configuration in resources has the advantage of both hiding the configuration string, and potentially making one fewer files to deploy.
This has always been an interesting one to answer. It all depends on your current situation and needs.
Will you have to change the
connection string post deploy?
Security considerations -> Someone
might be able to get access to your
database from the stored credential.
(How much permissions does that
credential have?, etc..)
If you want the flexibility to change connection strings easily post deploy, that maybe app.config might be easiest option.
If security is a concern, then you could look at two things.
Locking down permission on that
credential (only give the minimum
required rights for you app to work)
Encrypting your connection string.
(Have a look at MS Enterprise
Library, from memory they will store
the connection string encrypted and
decrypt for you)
Storing connection string in
registry
Encrypting and storing connection
string in registry (If it is a major concern. It about making it harder for the hacker.)

Using the database to hold application settings

I am looking at ways to make our application more extensible and easier to manipulate without having to alter the web.config (or, in our case, application.config files, which contain the appsettings node).
One way I have thought about is keeping the app settings in the database table that has a sqlcachedependancy. This means that:
Any time a setting is changed in the database, the cache is invalidated, and the settings are retrieved again, thus updating the application in realtime without having to alter files and restart the entire app.
We can create a custom tool which allows us to alter the settings.
The cons as I see it are that this may cause serious logic problems in that, if you have something that checks an appsetting at the start of a process, and it then changes halfway through, you could end up unintentionally altering the process flow, as the requirement for a complete application restart is negated.
Is there a way round this?
Is there a better way to manage appsettings, so that you can alter them on the fly remotely for one, several, or all servers in one go?
I think you've nailed the two major players:
either you have access to the file system and you put all your settings in a plethora of *.config files there
OR:
you don't have access (or only very limited access) to the server's file system and thus you're probably better off putting config settings and user preferences in a database, basically leaving nothing but the connection string to the config file on disk
Both approaches have their pros and cons. I've been trying for a long time to find a way to "materialize" a config section from a database field, so that I could basically just use the config XML, but stored in a database field. Unfortunately, the entire .NET 2.0 config system is very much "locked down" and just only assumes data will come from files - there's no way to plug in e.g. a database provider to allow the config system to read its contents from a database field :-( Really too bad!
The only other approach I've seen is a "ConfigurationService" in the StockTrader 2.0 sample app provided by Microsoft, but for my needs, it felt like overkill and like a really complex, really heavy-weight subsystem.
You could use SQLite, which will be a self-contained DB in a single file. Two birds with one stone?
If you reference an external config file that contains appsettings (leaving everything else in the normal app.config) then I believe editing it only reloads those settings, it doesn't force the whole app to restart.
There's a similar question on the subject here:
Nested app.config (web.config) files
WRT the problem of values changing in the middle of program execution, I guess you could locally cache the values, and raise an event when they change, allowing routines to reach a suitable point before using the updated values.
I think in asp.net we sort of get this for free because each page lifecyle is distinct, so the value is simply applied to new page requests only, not in the middle of an execution.
Edit: A little extra info:
Configuration Changes Cause a Restart of the Application Domain
From MSDN:
Changes to configuration settings in Web.config files indirectly cause the application domain to restart. This behavior occurs by design. You can optionally use the configSource attribute to reference external configuration files that do not cause a restart when a change is made. For more information, see configSource in General Attributes Inherited by Section Elements.
More information on the ConfigurationManager class in the System.Configuration namespace which could be used to modify the config files programatically (ie in a custom tool, if relevant disk read permissions can be provided). If you stick to using the built in configuration classes, I think changing the external configs, would not cause application restart, but would raise events (such as property changed) which you could handle, to ensure your code is not caught out by changing settings.

Categories