locked
WebConfigModification Issues RRS feed

  • Question

  • I have a little issue here regarding the modification of Web.Config files in Feature Stamping (SP2010 [Web Application Level Feature, Activate on default])

    I’m facing two strange Issues

    1. The applied modification like (adding a child node) appears multiple times in web.config.
    2. At feature deactivating, I’m removing the modification against the owner, it gets the modification, but These are not removed.

    I’m using the follow code snip during Feature Activation.

    ModificationEntry[] enries =
                {
                    new ModificationEntry("someName", "someSection", SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode)
                };

                SPWebApplication WebApp = (SPWebApplication)properties.Feature.Parent;
                WebApp.WebConfigModifications.Clear();

                foreach (ModificationEntry entry in enries)
                {
      // CreateModification simply return me SPWebConfigModification
                    SPWebConfigModification configModificationItem = CreateModification(entry, properties.Feature.DefinitionId.ToString());
                    if (!WebApp.WebConfigModifications.Contains(configModificationItem))
                    {
                        WebApp.WebConfigModifications.Add(configModificationItem);
                    }
                }

                WebApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                WebApp.Update();


    This is what I’m doing at feature deacting. 


    if (webApp != null)
                {
                    Collection<SPWebConfigModification> collection = webApp.WebConfigModifications;
                    int iStartCount = collection.Count;

                    // Remove any modifications that were originally created by the owner.
                    for (int c = iStartCount - 1; c >= 0; c--)
                    {
                        SPWebConfigModification configMod = collection[c];
                        if (configMod.Owner == properties.Feature.DefinitionId.ToString())
                            collection.Remove(configMod);
                    }

                    // Apply changes only if any items were removed.
                    if (iStartCount > collection.Count)
                    {
                        webApp.Update();
                        webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                    }
                }


    Please Comment !


    Usman
    jeudi 3 février 2011 14:11

Toutes les réponses

  • To start with, I think you may have the last two lines of this passage in the wrong order:

                foreach (ModificationEntry entry in enries)
                {
                     // CreateModification simply return me SPWebConfigModification
                    SPWebConfigModification configModificationItem = CreateModification(entry, properties.Feature.DefinitionId.ToString());
                    if (!WebApp.WebConfigModifications.Contains(configModificationItem))
                    {
                        WebApp.WebConfigModifications.Add(configModificationItem);
                    }
                }
                WebApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                WebApp.Update();
    I think the general rule is that you first Update the web app to save your changes to the WebConfigModifications property and then call ApplyWebConfigModifications, which will iterate through the property and apply each modification it finds in there.
    Try reversing them and see if that fixes it or at least changes the symptoms.

    Rick - MSFT
    jeudi 3 février 2011 20:49
  • Hi,

    You can try it  with the following code.

    e.g.

    SPWebService myService =webApp.WebService;
    myService.Update(); 
    myService.ApplyWebConfigModifications();
    
    
    

    Microsoft Online Community Support
    vendredi 4 février 2011 07:05
  • Hi, 

    Thanks for suggestions!

    I tried both of the suggestions, but nothing worked. 

    What I found now, is that if I deploy my solution using Visual Studio 2010, and if my feature "WebConfigFeature" is set as "Actiavate on Default", the entries in web.config file will be multiple, but

    If, I deploy my solution without activating the feature from Visual Studio, and Activate it later from UI/command line, The web config entry is added only once (Strange) but I'm facing it.

    But the other issue is still there, on feature deactivating, Its not removing the entries from web.config. 

    Advise !


    Usman
    vendredi 4 février 2011 11:16
  • There is a known bug where sometimes ApplyWebConfigModifications does not actually write to the physical web.config, but it does add the modification to the configuration database and the system does behave as if the modification was applied. Maybe what you are seeing is another symptom of essentially the same bug.

    Could you try something for me?  Start with a clean web.config. Do your activation and, regardless of whether the change is written to the physical web.config, test to see if the system behaves as if the modification has been applied. Then deactivate and, regardless of whether the element is removed from the physical web.config, test to see if the system behaves as if it were removed.


    Rick - MSFT
    vendredi 4 février 2011 17:15
  • Here's the code that I use to add and remove web.config modifications in a feature event receiver:
    http://blog.beckybertram.com/Lists/Posts/Post.aspx?ID=131


    Blog: blog.beckybertram.com | RSS | @beckybertram | SharePoint 2010: Six-in-One
    vendredi 4 février 2011 21:19
  • Hi,

    Thanks for you time, but its really killing me.

    I tried everything, and follow your way as well, started off with the fresh web.config Add node nodes and the check the system, system behaves normal.

    But then I tried to remove Modification, and got stuck. The modifications are still there.

     

    Actually, in my scenario, I need the modifications to be deleted from the physical file.

     

    Please comment!


    Usman
    dimanche 6 février 2011 00:11
  • But then I tried to remove Modification, and got stuck. The modifications are still there.

    Actually, in my scenario, I need the modifications to be deleted from the physical file.

    I understand you want the modification removed from the physical file, but for purposes of determining whether this is a variation of a known bug I need to know whether the system behaves as if the modification was removed, even if the modification is still present in the physical file.
    Rick - MSFT
    dimanche 6 février 2011 03:16
  • Hi, 

    Just got back to work, tried what you suggested and got that even after removing the webConfigModification (not on physical file) the system behaves as if the modification are still there.

    Give you more, let see my scenario 

    I have a custom HttpModule on each request and configure it by adding a entry to webConfig Midifcation so onto physical web.config at feature activation.

    After activation, the system behaves as it should and each request is caught by my handler.

    When I deactivated the feature, the modifications are removed with entries on physical files left, and system still assumes my handler.

    I hope I answer your question.

    for more convenience I m putting all code now ............

     

    //Feature Activation

    public override void FeatureActivated(SPFeatureReceiverProperties properties)

            {

                SPWebApplication WebApp = (SPWebApplication)properties.Feature.Parent;

                ModificationEntry[] enries =

                {

                    new ModificationEntry("add[@key='DLWHTTPHandler']", "configuration/system.web/httpModules", "<add name=\"DLWHandler\" type=\"PWP.DirectLink.RequestHandling.RequestModule, PWP.DirectLink.RequestHandling, Version=1.0.0.0,  Culture=neutral, PublicKeyToken=15cdbbb26f475ef2 \" />", SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode)

                };

                foreach (ModificationEntry entry in enries)

                {

                    Logger.LogInfo(Logger.DiagnosticsCategory.SiteProvisioning, "Adding Entry to Web Config: ");

                    SPWebConfigModification configModificationItem = CreateModification(entry, properties.Feature.DefinitionId.ToString());

                    if (!WebApp.WebConfigModifications.Contains(configModificationItem))

                    {

                        WebApp.WebConfigModifications.Add(configModificationItem);

                    }

                }

                WebApp.Update();

                WebApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

            }

    // Feature Deactivation
     public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
            {
                SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;
                this.RemoveWebConfigModifications(webApp, true, properties.Feature.DefinitionId.ToString());
            }

     public void RemoveWebConfigModifications(SPWebApplication webApp, bool checkOwner, string ownerId)

            {

                if (webApp != null)

                {

                    Collection<SPWebConfigModification> collection = webApp.WebConfigModifications;

                    int iStartCount = collection.Count;

                        // Remove any modifications that were originally created by the owner.

                        for (int c = iStartCount - 1; c >= 0; c--)

                        {

                            SPWebConfigModification configMod = collection[c];

                            if (configMod.Owner == ownerId)

                                collection.Remove(configMod);

                        }

                    // Apply changes only if any items were removed.

                    if (iStartCount > collection.Count)

                    {

                        webApp.Update();

                        webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

                    }

                }

            }

     private struct ModificationEntry

            {

                public string Name;

                public string XPath;

                public string Value;

                public SPWebConfigModification.SPWebConfigModificationType ModType;

                // Parameterized contructor.

                public ModificationEntry(

                    string Name, string XPath, string Value,

                    SPWebConfigModification.SPWebConfigModificationType ModType)

                {

                    // Intialize structure instances.

                    this.Name = Name;

                    this.XPath = XPath;

                    this.Value = Value;

                    this.ModType = ModType;

                }

            }

    private SPWebConfigModification CreateModification(ModificationEntry modEntry, string ownerId)

            {

                // Create and return SPWebConfigModification object.

                SPWebConfigModification modification;

                modification = new SPWebConfigModification(modEntry.Name, modEntry.XPath);

                modification.Owner = ownerId;

                modification.Sequence = 0;

                modification.Type = modEntry.ModType;

                modification.Value = modEntry.Value;

                return modification;

            }

     


    Usman
    lundi 7 février 2011 07:54
  • Thanks, Usman.

    I have added your code and scenario to the bug and raised its priority. To get faster action, it would be best if you opened a support bug with Microsoft support.  Tell them that the bug is "Office14 831708".


    Rick - MSFT
    lundi 7 février 2011 18:46
  • I have the same problem can u update the solution if any given by the microsoft support.
    vendredi 11 février 2011 10:00
  • Yes. This thread will be updated when a solution is found.


    Rick - MSFT
    vendredi 11 février 2011 18:10
  • Yes. This thread will be updated when a solution is found.


    Rick - MSFT

    Do you have any update on the bug "Office14 831708"?
    Microsoft MVP C# || gabrielmongeon.com || LinkedIn
    jeudi 4 août 2011 19:59
  • No. The bug has not been fixed yet. In the meantime open the sdk topic http://msdn.microsoft.com/en-us/library/bb861909.aspx and scroll down to the Community Content section. Another user has suggested that a certain PowerShell script may need to be run.
    Rick - MSFT
    jeudi 4 août 2011 22:56
  • No. The bug has not been fixed yet. In the meantime open the sdk topic http://msdn.microsoft.com/en-us/library/bb861909.aspx and scroll down to the Community Content section. Another user has suggested that a certain PowerShell script may need to be run.
    Rick - MSFT


    Hi Rick,

    The PowerShell workaround does not work for me. I tested the value of RemoteAdministratorAccessDenied prior to running the code and it's set to false.

    My issue is that I add some HttpModule in the Web.Config, but it does not remove it, so if I re-deploy my solution, the whole site is down (error 500) due to a double HttpModule in the Web.Config. It can easily be manually fixed, but since we are selling our products to our customers, this is quite not acceptable for a customer point of view... Hope it's going to make it in future fixes...

    I guess they are no way to track this bug for us outside of MS?


    Microsoft MVP C# || gabrielmongeon.com || LinkedIn
    vendredi 5 août 2011 13:05
  • This is a known bug. It will be several more months before it is fixed unless I can get one or more customers to make an official request for a fix. If you are willing to volunteer, please reply to this thread with your email address and I will contact you with details.

    Thanks.


    Rick - MSFT
    jeudi 11 août 2011 20:44
  • This is a known bug. It will be several more months before it is fixed unless I can get one or more customers to make an official request for a fix. If you are willing to volunteer, please reply to this thread with your email address and I will contact you with details.

    Thanks.


    Rick - MSFT

    Hi-

    I have the same issue.  I deploy a solution and web.config is modified just fine.  When I retract it, modifications made to web.config aren't removed.  If the solution is redeployed, the same modifications are added to web.config again.  In my case, I'm adding bindings for a WCF service.

    We are an MS customer and are willing to request a fix if need be.  sbrown @at@ huntoil .dot. com.

    Thanks.

    vendredi 11 novembre 2011 16:12
  • This is a known bug. It will be several more months before it is fixed unless I can get one or more customers to make an official request for a fix. If you are willing to volunteer, please reply to this thread with your email address and I will contact you with details.

    Thanks.


    Rick - MSFT

    Hi-

    I have the same issue.  I deploy a solution and web.config is modified just fine.  When I retract it, modifications made to web.config aren't removed.  If the solution is redeployed, the same modifications are added to web.config again.  In my case, I'm adding bindings for a WCF service.

    We are an MS customer and are willing to request a fix if need be.  sbrown @at@ huntoil .dot. com.

    Thanks.


    We solved our issue: you need to use a VALID XPath in the Name property of the SPWebConfigModification class. See the remarks here. I think is a bug/wrong behavior since you already have the Path property in SPWebConfigModification...

    Try it and let us know if it works for you.

    And no fix will be made for this issue and won't be fixed in the next Service Pack.


    Microsoft MVP C# || gabrielmongeon.com || LinkedIn
    lundi 14 novembre 2011 15:22
  • We solved our issue: you need to use a VALID XPath in the Name property of the SPWebConfigModification class. See the remarks here.
    Microsoft MVP C# || gabrielmongeon.com || LinkedIn


    Not having a valid XPath for the Name property may have been the issue in your case, but that is not generally the issue. There are cases where the problem is present even when the Name property is a valid XPath. Usman's longer example above from Feb 7th, for example, has a valid XPath in the Name property.

    Are you saying (contrary to the SDK topic to which you linked), that the Name property has to be  the FULL absolute XPath (as distinct from the XPath relative to the parent path in the Path property)? 


    Rick - MSFT

    lundi 14 novembre 2011 20:22
  • Are you saying (contrary to the SDK topic to which you linked), that the Name property has to be  the FULL absolute XPath (as distinct from the XPath relative to the parent path in the Path property)? 


    Yes, this is what I'm saying (I'm no way an XPath expert), but if you make 1 error in XPath in the name, it will fail.

    Example, this is currently what I have for an handler: 

    handlerModification.Path= "configuration/system.webServer/handlers";
    handlerModification.Name ="add[@name='FindabilityCAP'][@path='clientaccesspolicy.xml'][@verb='*'][@type='MyNamespace.Handlers.ClientAccessPolicyHttpHandler, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6ff2ece7d9388498'][@resourceType='Unspecified'][@preCondition='integratedMode']";
    handlerModification.Value="<add name='FindabilityCAP' path='clientaccesspolicy.xml' verb='*' type=MyNamespace.Handlers.ClientAccessPolicyHttpHandler, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6ff2ece7d9388498' resourceType='Unspecified' preCondition='integratedMode' />";
    
    

    And for an assembly:

    assemblyModification.Path= "configuration/system.web/compilation/assemblies";
    assemblyModification.Name = "add @assembly='Alcero.Products.Reperio, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6ff2ece7d9388498']";
    assemblyModification.Value = "<add assembly=MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6ff2ece7d9388498' />";
    
    So this is the configuration that actually work on 2 of our solution, and I must say that the Name property is way more than a sample name. Even MS SharePoint support team did not realize that when they helped us in the first place.


    Microsoft MVP C# || gabrielmongeon.com || LinkedIn
    mardi 15 novembre 2011 14:20
  •  if you make 1 error in XPath in the name, it will fail.

    OK. But based on your samples, the FULL XPath is NOT required in the Name attribute. Rather, the Name attribute has the relative path (relative to the value of the Path attribute).  So the existing documentation is correct.

    And there is a bug here. SharePoint code can have correct Path, Name, and Value parameters and still experience these symptoms of this thread.


    Rick - MSFT
    mardi 15 novembre 2011 22:14
  • I don't know if this got fixed by MSFT but i found a solution which worked for us. To avoid duplicate entries try this:-

    Lets say you want to add a config entry for Mschart Control inside the configuration/system.webServer/handlers section as:-

    <add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD,POST" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

     1. Try to add key add[@name=\"ChartImageHandler\" and you'll notice it gets updated multiple times in few occasions if you you use default activation of the feature

    2. Now try adding a section to remove the entry which in this case will be <remove name=\"ChartImageHandler\" /> prior to adding the entry.

    3. This will still not work if your web.config is adding <remove >section prior to the <add > section which will happen as the entries are updated alphabetically

    4. You can try to cheat this a bit by adding a condition in front of the path element which equated to true eg.

    for path element for remove entry try path = "configuration/system.webServer/handlers[1=1]" and for the add entry try path = "configuration/system.webServer/handlers[2=2]"

    This fixed it for us. Hope this helps!


    Lalit Joshi

    mercredi 27 juin 2012 23:26