app.Config file entries are cleared on Repair installed Setup - winforms

I have created a Setup Project for my Project. This project connects to a live DB server through asmx services. That URL will be determined after the client will deploy the web services on some server. So in setup project i have added a "TextBoxes" dialog in User Interface Editor section of the Setup Project where i have enabled only one TextBox to get the URL of the deployed Services. In my project i have added a file to be executed during Setup installation and i have defined it as follows:
[RunInstaller(true)]
public class InstallerHelper : System.Configuration.Install.Installer
{
// Other Code also exists that is not needed to be shown here<br/>
//.....
// The following method gets executed during setup installation
public override void Install(IDictionary stateSaver)
{
try
{
base.Install(stateSaver);
//Proceed only if the Context object has some parameters
if (Context.Parameters.Count != 0 && !string.IsNullOrEmpty(Context.Parameters["WEBSITEURL"]))
{
//Get the installation Folder's Path
string installationFolder = Context.Parameters["INSTALLFOLDER"];
// Get the Site's URL entered by Client
string websiteUrl = Context.Parameters["WEBSITEURL"];
//Create different Key Value pairs based on entered URL
string[][] keyValues = {
new string[] {"SiteUrl",websiteUrl},
new string[] {"WebServiceURL", websiteUrl + "Users.asmx" },
new string[] {"TicketsServiceURL", websiteUrl + "Tickets.asmx"},
new string[] {"CampaignsAndProjetcsServiceURL", websiteUrl + "CampaignsAndProjetcs.asmx"},
new string[] {"EntitiesURL", websiteUrl + "Entities.asmx"},
new string[] {"AccountsURL", websiteUrl + "Accounts.asmx"},
new string[] {"TransactionsURL", websiteUrl + "Transactions.asmx"},
new string[] {"RelatedReportsURL", websiteUrl + "RelatedReports.asmx"},
new string[] {"GiftAidsURL", websiteUrl + "GiftAids.asmx"}
};
// Load the app.Config file and store these values in it.
//********************************************
string configFilePath = installationFolder + #"\MyProject.exe.config";
XmlDocument configuration = new XmlDocument();
// Load App.Config File
configuration.Load(configFilePath);
//Add the values in it
Utility.UpdateValue(keyValues, configuration);
//Save configuration File
configuration.Save(configFilePath);
//********************************************<br/>
}
}
catch (Exception ex)
{
throw new InstallException("The following Error(s) occured during installation. \n " + ex.Message);
}
}
}
Here i Store the entered URL and some other generated URLs of different web services in App.Config of the Project to be used in Project for accessing data.
It works fine when i install a fresh copy of the Setup, but problem occurs when i try to Repair the installed project by again executing the Setup.exe file.
Repair process does not asks me to enter the URL again and also the Items stored in App.Config during first time installation are lost. So the whole application stops working.
Any help is greatly appreciated

A good approach is to save this custom information somewhere and retrieve it during maintenance using searches:
create some string registry entries which contain your custom properties; the registry entry value can be something like:
[WEBSITEURL]
create registry searches which read these entries and save them in your custom properties; for this use the property names for the actual searches
This way a repair will read the property values from registry and restore your original properties.
Both the Registry Editor and Launch Conditions Editor can be opened by selecting your setup project in Solution Explorer and clicking the appropriate button on its top pane.

Related

Xamarin Forms - How do i use a Premade Local Database? [Solved] [duplicate]

I have started using the Xamarin plugin for Visual Studio to create an Android app.
I have a local SQL database, and I want to call it to display data. I don't see how I can do this. Is it possible?
After thinking this was a trivial thing to do, I was proven wrong when I tried setup a quick test project. This post will contain a full tutorial on setting up a DB for an Android App in Xamarin that will come in handy as a reference for future Xamarin users.
At a glance:
Add Sqlite.cs to your project.
Add your database file as an Asset.
Set your database file to build as an AndroidAsset.
Manually copy the database file out of your apk to another directory.
Open a database connetion using Sqlite.SqliteConnection.
Operate on the database using Sqlite.
Setting up a local database for a Xamarin Android project
1. Add Sqlite.cs to your project.
Start by going to this repository and downloading Sqlite.cs; this provides the Sqlite API that you can use to run queries against your db. Add the file to your project as a source file.
2. Add DB as asset.
Next, get your DB and copy it into the Assets directory of your Android project and then import it into your project so that it appears beneath the Assets folder within your solution:
I'm using the Chinook_Sqlite.sqlite database sample renamed to db.sqlite from this site throughout this example.
3. Set DB to build as AndroidAsset.
Right click on the DB file and set it to build action AndroidAsset. This will ensure that it is included into the assets directory of the APK.
4. Manually copy DB out of your APK.
As the DB is included as an Asset (packaged within the APK) you will need to extract it out.
You can do this with the following code:
string dbName = "db.sqlite";
string dbPath = Path.Combine (Android.OS.Environment.ExternalStorageDirectory.ToString (), dbName);
// Check if your DB has already been extracted.
if (!File.Exists(dbPath))
{
using (BinaryReader br = new BinaryReader(Android.App.Application.Context.Assets.Open(dbName)))
{
using (BinaryWriter bw = new BinaryWriter(new FileStream(dbPath, FileMode.Create)))
{
byte[] buffer = new byte[2048];
int len = 0;
while ((len = br.Read(buffer, 0, buffer.Length)) > 0)
{
bw.Write (buffer, 0, len);
}
}
}
}
This extracts the DB as a binary file from the APK and places it into the system external storage path. Realistically the DB can go wherever you want, I've just chosen to stick it here.
I also read that Android has a databases folder that will store databases directly; I couldn't get it to work so I've just ran with this method of using an existing DB.
5. Open DB Connection.
Now open a connection to the DB through the Sqlite.SqliteConnection class:
using (var conn = new SQLite.SQLiteConnection(dbPath))
{
// Do stuff here...
}
6. Operate on DB.
Lastly, as Sqlite.net is an ORM, you can operate on the database using your own data types:
public class Album
{
[PrimaryKey, AutoIncrement]
public int AlbumId { get; set; }
public string Title { get; set; }
public int ArtistId { get; set; }
}
// Other code...
using (var conn = new SQLite.SQLiteConnection(dbPath))
{
var cmd = new SQLite.SQLiteCommand (conn);
cmd.CommandText = "select * from Album";
var r = cmd.ExecuteQuery<Album> ();
Console.Write (r);
}
Summary
And that's how to add an existing Sqlite database to your Xamarin solution for Android! For more information check out the examples included with the Sqlite.net library, its unit tests and the examples in the Xamarin documentation.
Here is the one that I'm using and it's working
install the Sqlite plugin
create interface to access different platforms services
create a model for the table
implement the interface that you created earlier on all of the
platform you want to use
use the plugin to create, get, insert, etc on your table
for more detailed information check this

Content migration error from Ektron to EpiServer

I am working on a content migration project , from Ektron 9 to EpiServer 8, the first task is to migrate the content of specific pages , to achieve that, I was following Ektron's API guidance Ektron Developer API
1- I am approaching this migration the right way? right now I just added Ektron Dll as a reference in my app. I tried to use their web services , but it doesn't have the data i need (content of specific pages).Ektron Web Services
here's a snippet of my code:
GetAllTemplatesRequest cc = new GetAllTemplatesRequest();
//var UserCRUD = new Ektron.Cms.Framework.User.UserManager();
var UserCRUD = new UserManager();
string Token = UserCRUD.Authenticate("admin", "password");
if (!string.IsNullOrEmpty(Token)) // Success
{
try
{
//Create the Content Object set to observe permissions
Ektron.Cms.Framework.Content.ContentManager ContentAPI
= new Ektron.Cms.Framework.Content.ContentManager(ApiAccessMode.Admin);
//Retrieve the content
Ektron.Cms.ContentData contentData;
contentData = ContentAPI.GetItem(30);
//Output the retrieved item's content
var cs = contentData.Html;
}
catch (Exception _e)
{
throw _e;
}
}
else // Fail
{
}
But I am getting this error:
This is what i ended up doing :
As there are many ways to perform the migration , I chose the approach of focusing mainly on EpiServer APIs to create new content , blocks, and assets ; and get all the content i need from Ektron using SQL statements.
Ektron Save all the content in a table named content .
The pages are organized in “Folder structure” fashion , so every page is in a “Folder”
to get the folder ID for a specific page, you can use this query :
select folder_id from content where content_id = 2147485807
with that folder id you can get all the pages listed under that specific folder; for instance you will need to get all the pages under “Articles”.
Then i used that folderID in this query:
SELECT [content_id]
,[content_title]
,[content_html]
,[date_created]
,folder_id
,[content_teaser]
,[content_text]
,[end_date]
,[content_type]
,[template_id]
, content_status
FROM content
where folder_id=(select folder_id from content where content_id = 2147485807)
order by content_title
FOR XML PATH(‘Article’), ROOT (‘Articles’)
which Creates an XML for me ready to consume in my EpiServer code.
The first thing in EPI server I did is to add a new property in the SitePageBase model to add a “LegacyContentID” that will serve as a mapping entry in case i need to access/modify the content of the new created pages. it serves as a link between the data imported from Ektron and the new data i am creating on EPI server.
[Display(
Name = “Legacy Content ID”,
Description = “Content ID from Ektron imported data , for migration purposes”,
GroupName = GroupNames.PageSettings,
Order = 37)]
[ScaffoldColumn(false)]
[Editable(false)]
public virtual string LegacyContentID { get; set; }
Then i created a method to create the article pages , the only parameter it needs is the parentID from IP server (you can create a new page in EpiServer and then under properties of that page you can the page ID).
public void CreateArticlesPages(int parentID)
{
IContentRepository contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var parentlink = new ContentReference(parentID);
XmlDocument doc = new XmlDocument();
doc.LoadXml(File.ReadAllText(#”Articles.xml”));
string jsonText = JsonConvert.SerializeXmlNode(doc);
dynamic data = JsonConvert.DeserializeObject(jsonText);
for (int i = 0; i < data.Articles.Article.Count; i++)
{
var PageImportedObject = data.Articles.Article[i];
ArticlePage page = contentRepository.GetDefault<ArticlePage>(parentlink);
page = contentRepository.GetDefault<ArticlePage>(parentlink);
page.LegacyContentID = PageImportedObject.content_id;
page.Name = PageImportedObject.content_title;
page.PageTitle = PageImportedObject.content_title;
if (PageImportedObject.content_teaser == null)
page.Summary = “No Summary from the Ektron DB”;
else
page.Summary = PageImportedObject.content_teaser;
page.Description = PageImportedObject.content_html.root.Description;
contentRepository.Save(page, EPiServer.DataAccess.SaveAction.Save, EPiServer.Security.AccessLevel.NoAccess);
contentRepository.Save(page, EPiServer.DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);
}
}
The code above creates a new page of type “ArticlePage” and add content from the XML generated earlier holding Ektron’s info.
Just coping one dll from an Ektron site into another site will not work.
The Web services idea was a better one. There are web service calls to get the content by id.
Alternatively you could write your own web service that runs inside the ektron site and uses the Ektron API to expose the data you want. Then call that service from the other site.
You will want to review the content migration starter kit. https://github.com/egandalf/ContentTransferStarterKit

dyanamically change the database name in SqlMapConfig.xml file

I want to change the database name in SqlMapConfig.xml file from the application, does any one help me?
You can override the database when you instantiate the Ibatis mapper instance; I do this for switching between debug and release builds of the application and hence accessing a different target database.
If your xml file is in an assembly called DatalayerAssembly for example, you might have a method for returning your new Ibatis instance based on a database name like this:
public IBatisNet.DataMapper.ISqlMapper CreateNewIbatis(
String serverName,
String databaseName)
{
// Load the config file (embedded resource in assembly).
System.Xml.XmlDocument xmlDoc = IBatisNet.Common.Utilities.Resources.GetEmbeddedResourceAsXmlDocument("SqlMapConfig.xml, DatalayerAssembly");
// Overwrite the connectionString in the XmlDocument, hence changing database.
// NB if your connection string needs extra parameters,
// such as `Integrated Security=SSPI;` for user authentication,
// then append that to InnerText too.
xmlDoc["sqlMapConfig"]["database"]["dataSource"]
.Attributes["connectionString"]
.InnerText = "Server=" + serverName + ";Database=" + databaseName;
// Instantiate Ibatis mapper using the XmlDocument via a Builder,
// instead of Ibatis using the config file.
IBatisNet.DataMapper.Configuration.DomSqlMapBuilder builder = new IBatisNet.DataMapper.Configuration.DomSqlMapBuilder();
IBatisNet.DataMapper.ISqlMapper ibatisInstance = builder.Configure(xmlDoc);
// Now use the ISqlMapper instance ("ibatisInstance") as normal.
return ibatisInstance;
}
I'm using this approach in Ibatis 1.6.2.0 on .Net but the exact SqlMap config file might vary depending by version. Either way the approach is the same; you just might need a different Xml path (i.e. the bit that reads ["sqlMapConfig"]["database"] etc may need changing for your config file)
Hope that helps.

Can I grab the project output app.config file in the XML file Changes area of InstallShield 2012?

I need to change a couple paths from the debug/testing App.config files to their final home on the end user's machine. I see the XML File Changes option when editing the Installer project through Visual studio, and the help indicates I should Import the xml file to be changed.
BUT...
Is there any way to import the output of the project for the XML file? If I browse directly to the file itself I have to use the Debug or Release config file, which seems like it would be annoying. Otherwise I could use the base App.config but if any transformations are applied when building they'd be lost.
So am I stuck with just browsing to a file, or can I grab the "Project Output" somehow like I can for the .exe file?
XML File Changes is pretty weak tea.
To do what you are looking for your going to have to create a custom action that loads the .config file and updates it outside of InstallShield.
If you are using 2012 C# Wizard project type an option should be to create a .rul that catches the OnEnd() event in After Move Data. From the .rul call into a dll via UseDLL and invoke a method that accepts the target path to the config and the value to update the value to.
The following is code I'm testing so...
Using a C# Wizard project type I added the following InstallScript rule to call into a C# dll:
function OnEnd()
string basePath;
BOOL bResult;
string dllPath;
OBJECT oAppConfig;
begin
dllPath = TARGETDIR ^ APPCONFIG_DLL;
try
set oAppConfig = DotNetCoCreateObject(dllPath, "AppConfig.ConfigMgr", "");
catch
MessageBox("Error Loading" + dllPath + ": " + Err.Description, INFORMATION);
abort;
endcatch;
try
basePath = "C:\\Program Files (x86)\\MyCompany\\Config Test\\";
bResult = oAppConfig.ConfigureSettings(basePath + "appsettings.xml", basePath + "app.config", "someAppSection");
catch
MessageBox("Error calling ConfigureSettings " + dllPath + " " + Err.Number + " " + Err.Description, INFORMATION);
endcatch;
end;
C# test code:
public bool ConfigureSettings(string configFilePath, string targetAppConfigPath, string targetAppName)
{
bool completed = true;
try
{
XmlDocument configFileDoc = new XmlDocument();
configFileDoc.Load(configFilePath);
string installerTargetFileDoc = targetAppConfigPath; // InstallShield's build process for Visual Studio solutions does not rename the app.config file - Awesome!
System.IO.FileInfo fi = new System.IO.FileInfo(installerTargetFileDoc);
if (fi.Exists == false) installerTargetFileDoc = "app.config";
XmlDocument targetAppConfigDoc = new XmlDocument();
targetAppConfigDoc.Load(installerTargetFileDoc);
// ensure all required keys exist in the target .config file
AddRequiredKeys(configFileDoc.SelectSingleNode("configuration/" + targetAppName + "/requiredKeys"), ref targetAppConfigDoc);
// loop through each key in the common section of the configuration file
AddKeyValues(configFileDoc.SelectSingleNode("configuration/common/appSettings"), ref targetAppConfigDoc);
// loop through each key in the app specific section of the configuration file - it will override the standard configuration
AddKeyValues(configFileDoc.SelectSingleNode("configuration/" + targetAppName + "/appSettings"), ref targetAppConfigDoc);
// save it off
targetAppConfigDoc.Save(targetAppConfigPath);
}
catch (Exception ex)
{
completed = false;
throw ex;
}
return completed;
}
private void AddKeyValues(XmlNode configAppNodeSet, ref XmlDocument targetAppConfigDoc)
{
foreach (XmlNode configNode in configAppNodeSet.SelectNodes("add"))
{
XmlNode targetNode = targetAppConfigDoc.SelectSingleNode("configuration/appSettings/add[#key='" + configNode.Attributes["key"].Value + "']");
if (targetNode != null)
{
targetNode.Attributes["value"].Value = configNode.Attributes["value"].Value;
}
}
}
private void AddRequiredKeys(XmlNode targetAppNodeSet, ref XmlDocument targetAppConfigDoc)
{
foreach (XmlNode targetNode in targetAppNodeSet.SelectNodes("key"))
{
// add the key if it doesn't already exist
XmlNode appNode = targetAppConfigDoc.SelectSingleNode("configuration/appSettings/add[#key='" + targetNode.Attributes["value"].Value + "']");
if (appNode == null)
{
appNode = targetAppConfigDoc.SelectSingleNode("configuration/appSettings");
XmlNode newAddNode = targetAppConfigDoc.CreateNode(XmlNodeType.Element, "add", null);
XmlAttribute newAddNodeKey = targetAppConfigDoc.CreateAttribute("key");
newAddNodeKey.Value = targetNode.Attributes["value"].Value;
XmlAttribute newAddNodeValue = targetAppConfigDoc.CreateAttribute("value");
newAddNodeValue.Value = "NotSet";
newAddNode.Attributes.Append(newAddNodeKey);
newAddNode.Attributes.Append(newAddNodeValue);
appNode.AppendChild(newAddNode);
}
}
}
While it seems like it should work, Installshield is unable to grok project output correctly (dependencies are missed often, merge modules are duplicated even when they dont apply), or give you a way to deal with individual files in project output.
I have no less than 5 bugs open with them about problems using project output and their workaround is always "Add the files manually".
If you are just getting started with install shield, I suggest you try another alternative. If you have to use it, either complain about this not working to their support team and use the suggested workaround until they get it together.
This may not be the "answer" to your question, but hopefully helps your sanity when dealing with the broken feature set in this product.
You can import any file you want (by browsing), and make changes to it in any run-time location you like. I suggest just putting the minimal amount you need to make your changes; after all it's the XML File Changes view. That way most updates to the file won't cause or require any changes to your XML File Changes settings, no matter how it's included.

How to edit an external web.config file?

I am trying to write a winform application that would be able to edit the web.config file of an installed web application.
I have read through the ConfigurationManager and WebConfigurationManager class methods but I am unsure as to how I can open the configuration file of a web app and edit it.
I am looking for a method that does not require me to load the config file as a regular XmlDocument, although I am willing to do that if that is the only option available.
Any advice would be appreciated.
Ok so here is the answer, I have the EXACT same scenario. I wanted to write a winforms app to allow normal users to update the web.config. You have to go about getting the config a goofy way...
// the key of the setting
string key = "MyKey";
// the new value you want to change the setting to
string value = "This is my New Value!";
// the path to the web.config
string path = #"C:\web.config";
// open your web.config, so far this is the ONLY way i've found to do this without it wanting a virtual directory or some nonsense
// even "OpenExeConfiguration" will not work
var config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap() { ExeConfigFilename = path }, ConfigurationUserLevel.None);
// now that we have our config, grab the element out of the settings
var element = config.AppSettings.Settings[key];
// it may be null if its not there already
if (element == null)
{
// we'll handle it not being there by adding it with the new value
config.AppSettings.Settings.Add(key, value);
}
else
{
// note: if you wanted to you could inspect the current value via element.Value
// in this case, its already present, just update the value
element.Value = value;
}
// save the config, minimal is key here if you dont want huge web.config bloat
config.Save(ConfigurationSaveMode.Minimal, true);
Here is an example of what it does
Before:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="MyKey" value="OldValue" />
</appSettings>
<connectionStrings>
<add name="myConnString" connectionString="blah blah blah" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
After:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="MyKey" value="This is my New Value!" />
</appSettings>
<connectionStrings>
<add name="myConnString" connectionString="blah blah blah" providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<trust level="Full" />
<webControls clientScriptsLocation="/aspnet_client/{0}/{1}/" />
</system.web>
</configuration>
Just be careful, if you give it an invalid path, it will just create a config file at that path / filename. Basically, do a File.Exists check on it first
BTW, while you're at it, you could write a class that represents your settings in your web.config. Once you do this, write your getters/setters to read/write the settings in the web.config. Once THIS is done, you can add this class as a datasource and drag the databound controls onto your winform. This will give you a completely databound winform web.config editor that you can easily hammer out in a matter of minutes. I've got an example at work that I'll post tomorrow.
Fully featured winforms solution
So this is a relatively simple solution to writing a Gui to edit a web.config, some may say its overly complicated when notepad will do just fine but it works for me and my audience.
It basically works as described above, I wrote a class that had the configuration points that I wanted as properties. The ctor opens the file from a path and the getters / setters pull the data out of the returned configuration object, finally it has a save method that writes it out. With this class, I'm able to add the class as a datasource and drag / drop bound controls onto winforms. From there all you have to do is to wire up a button that calls the save method on your class.
Configuration class
using System.Configuration;
// This is a representation of our web.config, we can change the properties and call save to save them
public class WebConfigSettings
{
// This holds our configuration element so we dont have to reopen the file constantly
private Configuration config;
// given a path to a web.config, this ctor will init the class and open the config file so it can map the getters / setters to the values in the config
public WebConfigSettings(string path)
{
// open the config via a method that we wrote, since we'll be opening it in more than 1 location
this.config = this.OpenConfig(path);
}
// Read/Write property that maps to a web.config setting
public string MySetting
{
get { return this.Get("MySetting"); }
set { this.Set("MySetting", value); }
}
// Read/Write property that maps to a web.config setting
public string MySetting2
{
get { return this.Get("MySetting2"); }
set { this.Set("MySetting2", value); }
}
// helper method to get the value of a given key
private string Get(string key)
{
var element = config.AppSettings.Settings[key];
// it may be null if its not there already
if (element == null)
{
// we'll handle it not being there by adding it with the new value
config.AppSettings.Settings.Add(key, "");
// pull the element again so we can set it below
element = config.AppSettings.Settings[key];
}
return element.Value;
}
// helper method to set the value of a given key
private void Set(string key, string value)
{
// now that we have our config, grab the element out of the settings
var element = this.config.AppSettings.Settings[key];
// it may be null if its not there already
if (element == null)
{
// we'll handle it not being there by adding it with the new value
config.AppSettings.Settings.Add(key, value);
}
else
{
// in this case, its already present, just update the value
element.Value = value;
}
}
// Writes all the values to the config file
public void Save()
{
// save the config, minimal is key here if you dont want huge web.config bloat
this.config.Save(ConfigurationSaveMode.Minimal, true);
}
public void SaveAs(string newPath)
{
this.config.SaveAs(path, ConfigurationSaveMode.Minimal, true);
// due to some weird .net issue, you have to null the config out after you SaveAs it because next time you try to save, it will error
this.config = null;
this.config = this.OpenConfig(newPath);
}
// where the magic happens, we'll open the config here
protected Configuration OpenConfig(string path)
{
return ConfigurationManager.OpenMappedExeConfiguration(
new ExeConfigurationFileMap() { ExeConfigFilename = path },
ConfigurationUserLevel.None);
}
}
Build and then from there you can just goto your winform designer, goto Data > Show Data Sources (Shift+Alt+D). Right click > Add New Data Source and add it as an object as shown
Data Source Configuration Wizard 1 of 2 http://img109.imageshack.us/img109/8268/98868932.png
Data Source Configuration Wizard 2 of 2 http://img714.imageshack.us/img714/7287/91962513.png
Drag it (WebConfigSettings, the topmost) onto the winform. In my case, I will remove the navigator as that is for a List and I just have one.
Freshly added databound controls http://img96.imageshack.us/img96/8268/29648681.png
You should have something like webConfigSettingsBindingSource at the bottom of the designer (shown in the next pic). Goto the code view and change the ctor to this
public Form1()
{
InitializeComponent();
// wire up the actual source of data
this.webConfigSettingsBindingSource.DataSource = new WebConfigSettings(#"c:\web.config");
}
Add a save button to your winform
Save button added http://img402.imageshack.us/img402/8634/73975062.png
Add the following event handler
private void saveButton_Click(object sender, EventArgs e)
{
// get our WebConfigSettings object out of the datasource to do some save'n
var settings = (WebConfigSettings)this.webConfigSettingsBindingSource.DataSource;
// call save, this will write the changes to the file via the ConfigurationManager
settings.Save();
}
There, now you have a nice simple databound web.config editor. To add / remove fields, you just modify your WebConfigSettings class, refresh the datasource in the Data Sources window (after a build), and then drag n drop the new fields onto the UI.
You'll still have to wire up some code that specifies a web.config to open, for this example I just hard coded the path.
The cool thing here is all the value that a GUI adds. You can easily add directory or filebrowser dialogs, you can have connection string testers etc. All are very easy to add and very powerful to the end user.
I highly recommend you to use XElement along with LINQ enabled (LINQ to XML).
For instance you want to change the connectionString. This type of code is good enough
var connString = from c in webConfigXElement.appSettings.connectionString
where c.name == "myConnection"
select c;
and now you have full control over the <connectionString /> element, and do whatever you want to do with it.
I am referring you to MSDN for learning and also a Kick Start for instant working.
Hope this helps you to have full control over your .xml without pain.
Here you go, I wrote a toy app (VB.NET Windows client) that edits XML files using a Tree / Grid for navigating and editing.
You might get some ideas from it. The VS project file for it is here or just an MSI to install it is here, if you want to try it out on your web.config.
It loads the file into a DataSet (DataSet.ReadXML()) which parses it into DataTables, then displays and allows editing of the contents in a standard DataGrid. Then it will save the edited content back to the XML file (DataSet.WriteXML()).
All app.config and web.config are just XML files. You can open and edit them using XMLDocument, XMLWriter, etc.

Resources