locked
Using SPWebConfigModification code seems to clear all manual entries in the web.config file

    Question

  • Hi.

    I'm using SPWebConfigModification() ++ to add WCF service bindings and client configurations. The code where tested ok in development and test environment, but  it failed hard in the production farm. I activate the web.config changes in a feature scoped to the Web Application level. When I activated the feature (in production) it added my changes as it should, BUT it also cleared several of the manual changes that had been made to the web.config file (such as som Ajax settings). I did not clear all of my manual changes - just some.

    Bug? Anybody any idea on what was going on in my environment?

    Best regards,
    Frode

    Monday, March 02, 2009 6:46 AM

Answers

  •  To remove web.config entries you should make sure you check SPWebConfigModification owner before you remove them.  Don't remove them  thisApplication.WebConfigModifications.Clear(); 

    Also if you have a feature to add these entries then don't combine adding and removing entries together, remove entries on feature deactivate and add entries on feature activation. This to avoid calling ApplyWebConfigModifications() twice. This is very important in case of FARM deployment.

    Wednesday, March 04, 2009 7:53 PM
  • Yes it was the line thisApplication.WebConfigModifications.Clear(); that messed up my web.config.

    Thanx for your responses.

    Frode
    Thursday, March 05, 2009 6:37 AM

All replies

  • Hi Frode,

    SPWebConfigModification has several issues. This post may help you: http://blogs.devhorizon.com/reza/?p=459

    Regards,

    Blog de Barto Molina
    Microsoft MCP 6608632
    Monday, March 02, 2009 9:40 AM
  • Can you please post your code. 

    While working on SPWebConfigModification object one thing I found out that both "name" and "path" properties need to be carefully used as these two properties tells SPWebConfigModification object what need to be added/removed and where it can be added/removed.

    Monday, March 02, 2009 8:50 PM
  • I use the following code in the receiver class of the feature:

    //add all web.config entries 
    private void InsertWebConfigEntries(SPFeatureReceiverProperties properties) 
            { 
                if (!CheckEntries(properties)) 
                { 
                    using (SPSite site = properties.Feature.Parent as SPSite) 
                    { 
                        SPWebConfigModification dsEntry = GenerateWebConfigEntry("New config key""configuration/system.web/compilation/assemblies"
                            "<add assembly=\"Bartomolina.SharePoint.SPBM.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0123456789abcdef\" />", 100); 
     
                        SPWebApplication currentWebApp = site.WebApplication; 
     
                        currentWebApp.WebConfigModifications.Add(dsEntry); 
                        currentWebApp.WebService.ApplyWebConfigModifications(); 
                        currentWebApp.Update(); 
                    } 
                } 
            } 
     
    //check if the web.config entry exists. If you don't call this method you will get duplicate entries 
    private bool CheckEntries(SPFeatureReceiverProperties properties) 
            { 
                using (SPSite site = properties.Feature.Parent as SPSite) 
                { 
                    SPWebApplication currentWebApp = site.WebApplication; 
     
                    Collection<SPWebConfigModification> webConfigEntries = currentWebApp.WebConfigModifications; 
     
                    foreach (SPWebConfigModification entry in webConfigEntries) 
                    { 
                        if (entry.Owner == "ReceiverClass"
                        { 
                            return true
                        } 
                    } 
     
                    return false
                } 
            } 
     
    //new web.config entry 
    private SPWebConfigModification GenerateWebConfigEntry(string modName, string sXpath, string sKey, uint iSequence) 
            { 
                SPWebConfigModification configMod = new SPWebConfigModification(modName, sXpath); 
                configMod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode; 
                configMod.Name = string.Format("add[@name='{0}']", modName); 
                configMod.Owner = "ReceiverClass"
     
                configMod.Value = sKey; 
                configMod.Sequence = iSequence; 
     
                return configMod; 
            } 


    I hope it helps you.

    Blog de Barto Molina
    Microsoft MCP 6608632
    • Edited by bartomolina Wednesday, March 04, 2009 10:08 AM
    Monday, March 02, 2009 10:17 PM
  •   Hi.

    Thanx for the code. I do it very similar, but I've one extra line of code  (the one in bold), and I think that is the one creating the trouble:

                List<WebConfigModification.ModificationEntry> mods = GetModificationsAdd(masterSourceFolder, bindingName);

                thisApplication.WebConfigModifications.Clear(); //PROBLEM??

                foreach (WebConfigModification.ModificationEntry modEntry in mods)
                {
                    thisApplication.WebConfigModifications.Add(WebConfigModification.CreateModification(modEntry, this.GetType().FullName));
                }
                thisApplication.WebService.ApplyWebConfigModifications();
                thisApplication.Update();

    The highlighted line probably clears all previously web config modifications done. Right?

    I've had problems making the web.config modification process work right and therefore the extra line, BUT i think that line should NOT be there.

    - Frode

    Wednesday, March 04, 2009 7:32 AM
  • It's was not the manual entries in the web config that where cleared but those added by other features/solutions.

    Frode
    Wednesday, March 04, 2009 7:38 AM
  • You can try this for removing web.config entries added by your feature:

            //remove web.config entries owned by "ReceiverClass" 
            private void deleteWebConfigEntries(SPFeatureReceiverProperties properties) 
            { 
                using (SPSite site = properties.Feature.Parent as SPSite) 
                { 
                    SPWebApplication currentWebApp = site.WebApplication; 
     
                    Collection<SPWebConfigModification> webConfigEntries =  
     
    currentWebApp.WebConfigModifications; 
                    Collection<SPWebConfigModification> webConfigEntriestoDelete = new  
     
    Collection<SPWebConfigModification>(); 
     
                    foreach (SPWebConfigModification entry in webConfigEntries) 
                    { 
                        if (entry.Owner == "ReceiverClass"
                        { 
                            webConfigEntriestoDelete.Add(entry); 
                        } 
                    } 
     
                    foreach (SPWebConfigModification entry in webConfigEntriestoDelete) 
                    { 
                        webConfigEntries.Remove(entry); 
                    } 
     
                    if (webConfigEntriestoDelete.Count > 0) 
                    { 
                        currentWebApp.WebService.ApplyWebConfigModifications(); 
                        currentWebApp.Update(); 
                    } 
                } 
            } 

    It doen't work for me because I am adding a key in "configuration/system.web/compilation/assemblies" that is actually not supported by SPWebConfigModifications (I should use something like custom CAS instead... :)). Try it and tell me if it worked for you!

    Blog de Barto Molina
    Microsoft MCP 6608632
    • Proposed as answer by bartomolina Thursday, March 05, 2009 7:05 AM
    Wednesday, March 04, 2009 10:14 AM
  •  To remove web.config entries you should make sure you check SPWebConfigModification owner before you remove them.  Don't remove them  thisApplication.WebConfigModifications.Clear(); 

    Also if you have a feature to add these entries then don't combine adding and removing entries together, remove entries on feature deactivate and add entries on feature activation. This to avoid calling ApplyWebConfigModifications() twice. This is very important in case of FARM deployment.

    Wednesday, March 04, 2009 7:53 PM
  • Yes it was the line thisApplication.WebConfigModifications.Clear(); that messed up my web.config.

    Thanx for your responses.

    Frode
    Thursday, March 05, 2009 6:37 AM