Editing Web.config programmatically - asp.net

What is a good way to edit a Web.config file programmatically?
I looked into System.Xml but couldn't find any obvious answers.

This fellow shows sample code if you still want to do it after all the caveats:
protected void EditConfigButton(object sender, EventArgs e)
{
Configuration objConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection("appSettings");
//Edit
if (objAppsettings != null)
{
objAppsettings.Settings["test"].Value = "newvalueFromCode";
objConfig.Save();
}
}
One valid reason for editing a web.config is to encrypt it, which is what that article is about.

You can use the WebConfigurationManager to read specific configuration sections. This will return a ConfigurationSection object. You can use this to read/modify the ConfigurationElements in the section. Once you have updated them, you can Save the ConfigurationSection and it will update the file with your changes.
I use this to automatically encrypt the appSettings and connectionStrings on Application_Start if they aren't already encrypted. I haven't actually changed any settings this way, but it seems like you ought to be able to do so.
Saving the updated configuration file may cause the app to recycle depending on how it is built.

Depending on what you are doing, the method is really a bit different in each situation. However the most robust method is to load it as an XmlDocument and modify it as needed via that method, but you MUST be careful to only modify it in the needed manner.

In theory; you could just generate a web config file programmatically and with some templating to make it easy.
However, if you're trying to edit your web.config from within the site; it's highly recommended you don't. At the very least; you'd trigger an app reset every time you updated it; which would be especially bad if you're using in-process sessions.
As Anders asked, what is it you're trying to do?

Yes I agree with Josh. I have tried this before and I've had two negative effects:
Slow loading if the current page after postback because ASP.NET is loading the web.config and all related resources
If you change the web.config early enough in the load cycle (e.g. global.asax events) the site may never load or fail in unpredictable ways

Agree with others, editing the webconfig is achievable, but has knock on effects are just to dangerous / risk involved
If its a value that is application specific, then it should be in an application specific config file

Lot of time you want to modify application specific settings after deployment like say when something is wrong e.g. switching the database connection in case current DB goes down. Moreover sometimes you want to create your own XML based configuration file which you want o modify programatically.
Try XML Webpad - http://xmlwebpad.codeplex.com/
Its a framework to view an edit XML files. Once you integrate it with your web app, editing web.config ill be as simple as viewing the web.config page, making the required changes and hitting the save button (all from within your application).

Related

Save a string for later use in ASP.NET

I have a simple string that I would like to save for later use on an ASP.NET server. It is an authorization string for a web service. It mostly stays the same, but may expire every few months. It will be saved programmatically from a code-behind file. Is there a simple place I can save it?
Initial thoughts are:
File - seems reasonable
Database - we don't have one setup and it seems like a lot of overhead to hold a string
Session - this would be too short lived
Config file - Based on answer from MK_Dev this would require a web app restart. No go then.
Somewhere else that I don't know about, but would be perfect?
Another possibility is to create a custom registry key. Here is an article with some code examples: Manipulating and Editing Registry with .NET.
If you don't mind restarting the app when the value changes, then config file is the way to go. If you need it to be fully dynamic, you can add a config table to the database and update it when changes.
How about server side cache?
Check this out: http://msdn.microsoft.com/en-us/library/18c1wd61%28v=vs.71%29.aspx
If the string remains static for the most part, I would store it in Cache with an expiration and/or dependency. If you go the dependency route, you can use a file or store the string in the database, and it will update automatically if and when it's changed.
See this article for details: Caching Application Data
How about System.Environment variables?
System.Environment.SetEnvironmentVariable("mystring","asdf");
System.Environment.GetEnvironmentVariable("mystring");

viewStateEncryptionMode="Always" not encrypting

Due to some security concerns i need to enable View State Encryption. I have viewstate & viewstateMAC turned off but i need to encrypt the "control state" string that is included in the __VIEWSTATE form parameter.
Currently my web.config looks like:
<pages enableViewState="false" enableViewStateMac="false">
When i set the following, in cassini, my viewstate is encrypted:
<pages enableViewState="false" enableViewStateMac="false" viewStateEncryptionMode="Always">
When i make the same change on my IIS 6 server, nothing happens.
I see the app domain recycle(Event: Application '/LM/W3SVC/...' located in 'C:...' initialized for domain '...'). when i touch web.config but i do not get encrypted viewstate as with cassini. I have tried Site Stop/Start, IIS Reset Stop/Start, Clear ASP.NET Temporary file cache. Anyone have any suggestions on what needs to be done to configure this?
I ran into a similar problem with this and it came down to the fact that if you pre-compile your site the web.config node for pages is ignored. You have to set those settings at compile to get it working. I know this is year late, but I figure if someone else comes here looking for solution to the problem this might be useful information.
A little blurb about this: http://blogs.msdn.com/b/asiatech/archive/2011/07/19/pages-settings-don-t-work-for-pre-compiled-asp-net-applications.aspx
(Link dead - blog pointed to this documentation: ASP.NET Web Site Project Precompilation Overview )
My customer had a viewstate MAC
validation problem. As a workaround, he wanted to disable the
viewstate MAC validation before find out the final solution. However,
he was still seeing the problems after added follow settings in the
configuration files.
Customer’s application is a pre-compiled ASP.Net application with
updatable option disabled. Looking at the code generated by compiler
with above settings, we found these settings are hard coded. So, this
means simply add the above setting into web.config doesn’t affect a
pre-compiled application. To make this taking affect, the application
has to be re-compiled.
[DebuggerNonUserCode]
private void __BuildControlTree(default_aspx __ctrl)
{
__ctrl.EnableViewStateMac = false;
__ctrl.EnableEventValidation = false;
__ctrl.ViewStateEncryptionMode = ViewStateEncryptionMode.Never;
This is a by-design behavior.

Is there anything wrong with modifying the web.config file dynamically

I read this article. I was planning on creating a setup page that runs and allows the user to change the sql connection strings which is stored in the web.config file. With some changes this may help in deployment or even development. My question is is it possible to change the connection string in the web.config file based on user input and is this advisable. N.B The connection string must be contained in the web.config
THank you
You may find helpful this blogpost on this topic.
hmmmm. Changing the web.config file would cause the app to restart. At least that's what would normally happen and from my understanding of the dependencies involved would happen if you did it from code.
That might be acceptable to you though & it is the best way to do it if the restart is acceptable.
Simon
It's possible to modify web.config based upon user input. It's just an XML file.
We do this as part of a custom action in an installer (MSI).
Modifying a web.config will cause the application pool to recycle though. Depending on your site, this (recycling) may or may not be a big deal.

Changing Global.asax variables from IIS

Can I change access or edit the values specified in Global.asax from IIS?? The reason is that I don't have the source code and the only change we need right now is to change the connection strings (database) specified in Global.asax.vb file.
Thanks!!
Usually, connection strings are specified in the Web.config for this very reason. If the values are hardcoded, there's no way for you to modify them unless you can change the code. You can setup an identical database (name, creds) and change some config settings so that your database server resolves to the same machine name. That's all I can think of...
Well, I was able to circumvent the issue. Not very elegant and might add to performance load, but was the simplest considering the work involved to recreate the project.
I created another aspx page and set the connection variables using the Application object in the Page's Page_Load, and then did a response.redirect to the previous default file. I was lucky as all code referred to the Application Object, and this was set only in Global.asax - had there been any code which directly specified the connection string - then I would be screwed!
The only overhead was that the Application_Start would be called only once - but overwriting those values with Page_Load will be called every time a request is made. Kind of trade-off I am ready to do.
I could not agree the previous answer as it mentioned the "Ideal" Case and the best practices - it did not solve my problem. The previous solution should be adopted if the previous sql server can be completely demoted.
Thanks Guys!

If my ASP.NET webapp isn't fit for runtime?

I want to run some tests when my ASP.NET webapp comes online (preferably before anyone tries to access it), to make sure all of my runtime dependencies are available as I expect them to be.
When is a good time to perform these tests (e.g. Application_Start, Application_Init, somewhere else, etc), and what's a good technique for making my webapp unavailable to users if my tests fail (it shares an app pool with other apps I don't want to affect)?
One approach would be to put your checks in the Application_Start event, and update a static property (or properties) in the Global class with the result of your test.
If you're using master pages, each master page (I've personally never seen more than 2 base master classes in a project) could check the static property in the Global class, and redirect to an "app offline" page if appropriate. Since the static property would only be updated when the application started, there shouldn't be any performance impact.
The code in your master page's OnLoad event might look like this...
if (!Global.WasDependencyCheckSuccessful)
{
//redirect to error page
}
If you're not using master pages, this may not be the best solution (because you would need to update each web form in your site individually).
You can put it in the Application_Start event in the global.asax.
To bring your app offline, simply create an App_Offline.htm file. I do it on our server by having an "App_Offline.html" file and when I need to bring it offline, I have the code rename it to change the extension from .html to .htm, and reverse that to bring it back online.
Of course, to bring it back online, you have to do it from code outside of your website, or do it manually, because if the file is there, the code in your website won't run...

Resources