Update Web.config Programmatically

If you are wondering how to change web.config programatically/runtime, this post will help you. Here I will show you how to update values in section and how to add section if it doesn’t exist in web.config.

Web.config is a XML file so here it how you can load web.config xml document.

XmlDocument doc = new XmlDocument();
bool change = false;
string configFile = Path.Combine(siteFolder, "web.config");
doc.Load(configFile);

//get root element
System.Xml.XmlElement Root = doc.DocumentElement;

I have created appSettings dictionary that holds key/value pairs that wanted to update in section.

Dictionary<string, object> appSettings = new Dictionary<string, object>();
appSettings.Add("EntityID", "1");
appSettings.Add("MarketID", "2");
appSettings.Add("MarketName", "Chicago");

Now the code below will go loop through each key/value pair under section and will compare the values in with appSettings dictionary. If it sees values are different, It will update in section.

XmlNode appNode = Root["appSettings"];
foreach (XmlNode node in appNode.ChildNodes)
{
   if (node.Attributes != null)
   {
     try
     {
        string key = node.Attributes.GetNamedItem("key").Value;
        string value = node.Attributes.GetNamedItem("value").Value;
        if (appSettings.ContainsKey(key) && value != appSettings[key].ToString())
        {
           node.Attributes.GetNamedItem("value").Value = appSettings[key].ToString();
           change = true;
        }
      }
      catch (Exception e)
      {
        auditLog.Warn("While reading the web.config, this line had no key/value attributes modify: " + node.InnerText);
      }
    }
}

That’s it!! Above code updates section if it finds there is a change that needs to be made. And here is the code that will add section if it doesn’t exist in web.config or update uiCulture and culture attributes if sections already exist and values of those attribute got changed.

//Get <system.web> node
XmlNode systemWebNode = Root["system.web"];

//find <globalization> node under system.web node
XmlNode globalizationNode = SelectGlobalizationNode(systemWebNode,doc);

if (globalizationNode != null)
{
  // found Globalization node in web.config.  So update Culture and UICulture attribute
  ChangeXMLAttributeValue(doc, globalizationNode, "uiCulture", config.LanguageUICulture, ref change);

  ChangeXMLAttributeValue(doc, globalizationNode, "culture", config.LanguageCulture, ref change);
}
else
{
  //no globalization xmlnode in web.config.  So create globalization node and set culture and uiculture attribute Note: Pass doc.DocumentElement.NamespaceURI to namespaceURI method parameter.

// If you pass "" empty string you will end up generating <globalization xmlns="" uiCulture="es-MX" culture="es-MX" /> and this will throw an error "Unrecognized attribute 'xmlns'. Note that attribute names are case-sensitive. ".

  XmlNode newGlobalizationNode = doc.CreateNode(XmlNodeType.Element, "globalization", doc.DocumentElement.NamespaceURI  );

  newGlobalizationNode.Attributes.Append(createXMLAttribute(doc, "resourceProviderFactoryType",
       "Emmis.Common.Globalization.EmmisResourceProviderFactory"));
  newGlobalizationNode.Attributes.Append(createXMLAttribute(doc, "uiCulture",config.LanguageUICulture));

  newGlobalizationNode.Attributes.Append(createXMLAttribute(doc, "culture", config.LanguageCulture));

  //Add <globalization> node under <system.web> node
  systemWebNode.AppendChild(newGlobalizationNode);

  change = true;
}

/// <summary>
/// This method will return globalization node if it finds under system.web node
/// </summary>
/// <param name="systemWebNode"></param>
private static XmlNode SelectGlobalizationNode(XmlNode systemWebNode, XmlDocument doc)
{

XmlNamespaceManager XmlNamespaces = null;
string XmlNamespacePrefix = "";

//Get default namespace
// this is very important part to get default name space.

// I was searching globalization node  like this doc.SelectNodes("globalization") and this was working when I was passing empty string to namespaceURI method parameter while creating <globalization> node. Line#: . But as I mentioned line# that won't work.  So below method is very importand otherwise you won't be able to find </globalization> section.

//To know more in detail about below method you can refere http://www.west-wind.com/Weblog/posts/2423.aspx
GetXMLNameSpaceInfo(doc, ref XmlNamespacePrefix, ref XmlNamespaces);

//Search <globalizatio> node in <system.web>
 XmlNode globalizationNode = systemWebNode.SelectSingleNode(XmlNamespacePrefix + "globalization", XmlNamespaces);

 return globalizationNode;
}

/// <summary>
/// Used to load up the default namespace reference and prefix information. This is required so that SelectSingleNode can find info in 2.0 or later config files that include a namespace on the root element definition. To know more in detail about below method you can refere http://www.west-wind.com/Weblog/posts/2423.aspx
/// </summary>
/// <param name="Dom"></param>
private static void GetXMLNameSpaceInfo(XmlDocument Dom, ref string XmlNamespacePrefix,ref XmlNamespaceManager XmlNamespaces)
{
  // *** Load up the Namespaces object so we can
  // *** reference the appropriate default namespace
  if (Dom.DocumentElement.NamespaceURI == null || Dom.DocumentElement.NamespaceURI == "")
  {
     XmlNamespaces = null;
     XmlNamespacePrefix = "";
  }
  else
  {
      if (Dom.DocumentElement.Prefix == null || Dom.DocumentElement.Prefix == "")
          XmlNamespacePrefix = "ww";
      else
          XmlNamespacePrefix = Dom.DocumentElement.Prefix;

      XmlNamespaces = new XmlNamespaceManager(Dom.NameTable);
      XmlNamespaces.AddNamespace(XmlNamespacePrefix,
                                           Dom.DocumentElement.NamespaceURI);

      XmlNamespacePrefix += ":";
   }
}

private static XmlAttribute createXMLAttribute(XmlDocument doc, string attributeName, string attributeValue)
{

  //XmlNode globalizationNode = doc.CreateNode(XmlNodeType.Element, "globalization", "");
  XmlAttribute attribute = doc.CreateAttribute(attributeName);
  attribute.Value = attributeValue;

  return attribute;
}

private static void ChangeXMLAttributeValue(XmlDocument doc, XmlNode globalizationNode, string attributeName, string newAttributeValue, ref bool change)
{

 XmlAttribute globalizationAttribute = null;

 globalizationAttribute = globalizationNode.Attributes[attributeName];

 if (globalizationAttribute == null)
 {
   globalizationNode.Attributes.Append(createXMLAttribute(doc, attributeName, newAttributeValue));
   change = true;
 }
 else
 {
   if (globalizationAttribute.Value != newAttributeValue)
   {
     globalizationAttribute.Value = newAttributeValue;
     change = true;
   }
 }
}

That’s it about section. So now you can update web.config file to save your changes. You might have noticed that I used “change” variable in the code and set that to true when we are updating some values in or section. If value of “change” variable is false, then we haven’t updated anything in web.config meaning all the values that we were going to update already in web.config so no need to update anything. The reason why I am checking is that if you make any changes to web.config, ASP.NET detects that changes and it will reload your application(recycle application pool) and effect of that is data kept in Session, Application, and Cache will be lost (assuming session state is InProc and not using a state server or database). So only save web.cofig if you have made changes in that. Now here is the final part of code to save web.config file.

if (change)  //Update web.config only if changes are made to web.config file
{
  try
  {
   doc.Save(configFile);
   auditLog.Debug("Updated web.config file");
  }
  catch (IOException ex)
  {
     auditLog.Debug("Error occured while saving web.config changes.");

     string logMsg = "Web.config update failed!  ExMsg: {0} {1} StackTrace: {2}";
     auditLog.Error(string.Format(logMsg, ex.Message, Environment.NewLine, ex.StackTrace));

     BusinessLayerException blx = new BusinessLayerException(busLayerExceptionMsg);
     throw blx;
   }

}
else
{
 auditLog.Debug("No need to update web.config file bcoz appsetting and globalization node values are accurate in web.config file");
}

That’s it…. You are done! :)

Tagged with:
Posted in Microsoft Technology
7 comments on “Update Web.config Programmatically
  1. Yassine says:

    Hi
    I have a exception :
    An error occured on page http://xxx:1314/Pages/xxx/xxx.aspx
    Method: mscorlib
    Error: L’accès au chemin d’accès ‘C:xxxxxxxx.xx.xxWeb.Config’ est refusé.
    Exception: UnauthorizedAccessException

    have you any idea ? thanks

  2. Shailesh says:

    @Yassine,

    By default website is running under ASPNET worker process account and that account need Read/Write permission to modify web.config file.

  3. be happy and love. kiss

  4. Mania says:

    Nice post about Update Web.config Programmatically | Broken Code. I am very impressed with the time and effort you have put into writing this story.

  5. Hiclereetle says:

    Thanks for council how I can thank you?

  6. ravi says:

    really helpfull.

  7. ravi kore says:

    how to add the cacheconfiguration/any setting into web.config or any config file, when user will add the reference of my dll(anyclasslibrary i.e. .dll ) into the application. Can it be possible ? just like the microsoft does, when we adds any reference of the cacheapplication block.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
Ads
OutbackDirect.co.uk is a trading site of World of Power.co.uk Limited. Outback Direct is the official Outback Consumer Warranty, Parts and Accessory Partners for the UK. We currently hold in stock 1000’s of parts and accessories for current and older Outback barbecues. We endeavour to ensure rapid and secure product delivery the length and breadth of mainland United Kingdom, this factor coupled with our excellent customer service has led to the market position we currently enjoy.
outback barbecue
omega 300 gas barbecue
Omega 250 Gas Hooded BBQ
------------------------------------------------------------ Silver Sky Imports is a unique online marketplace that offers unique handicrafts from Tibet and Nepal. Launched in 2003, Silver Sky Imports is currently the largest supplier of handmade items from the Himalayas. We specialize in the largest variety of Tibetan Singing Bowls and Crystal Singing Bowls online and include individual sound samples, pictures and descriptions for each bowl. Some of our other products include Tibetan Prayer Flags, Tingshas, Bell and Dorje, Incense, Felted Wool Handbags, Wood Masks, Prayer Wheels, Gongs, Bronze Statues, and Tibetan Meditation Rugs. monks
------------------------------------------------------------ Airpush, a mobile ad network that is only two years old, has quickly grown to one with over 5,000 advertisers. One thing they've heard from that sea of advertisers over the past 12 months, and especially over the past six, is that real-time bidding (RTB) capabilities are now a must. To answer those needs, the company today unveiled AirDSP, a platform meant to easily connect advertisers to RTB exchanges. Read more: Mobile RTB
------------------------------------------------------------ Danish site about electronic cigarettes E Cigarette, Electronic Cigarette and E Cigarettes e cigaret
------------------------------------------------------------ DrugRisks.com drugrisk​ recall ​informat​ion​ drugrisk​ yaz​
------------------------------------------------------------