1

I have read about best Practices for development once it comes to SPWebConfigModification and write feature to read xml file and modify web.config files and works fine on my local environment but once we try to deploy on test environment with multiple WFE and status keep saying Deploying and also once we try to enable webapplication level feature to modify web.config file its say "A web configuration modification operation is already running." I would like to take look at code and please advise if something wrong in my code. please find code below

public override void FeatureActivated(SPFeatureReceiverProperties properties) {
            //this.FeatureActivated(properties);
            this.ReadDeploymentSettings(properties);
            SPWebApplication webApplication = properties.Feature.Parent as SPWebApplication;
            Installer installer = new Installer() {
                WebApplicationId = webApplication.Id,
                Nodes = this.DeploymentNodes,
                DllsToGac = this.DllsToGac
            };

            installer.Deploy(Installer.DeploymentType.Deploy);
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties) {
            //this.FeatureDeactivating(properties);
            //this.ReadDeploymentSettings(properties);
            SPWebApplication webApplication = properties.Feature.Parent as SPWebApplication;
            Installer installer = new Installer() {
                WebApplicationId = webApplication.Id,
               // Nodes = this.DeploymentNodes,
               // DllsToGac = this.DllsToGac
            };

            installer.Deploy(Installer.DeploymentType.UnDeploy);
        }

Installer.cs

public class Installer {

        #region Enums

        /// <summary>
        /// Deployment type.
        /// </summary>
        public enum DeploymentType
        {
            /// <summary>
            /// Deploy.
            /// </summary>
            Deploy,

            /// <summary>
            /// Undeploy.
            /// </summary>
            UnDeploy
        }

        #endregion // Enums

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Installer"/> class.
        /// </summary>
        public Installer()
        {
        }

        #endregion // Constructors

        #region Proeprties

        /// <summary>
        /// Gets or sets the web application id.
        /// </summary>
        /// <value>The web application id.</value>
        public Guid WebApplicationId { get; set; }

        /// <summary>
        /// Gets or sets the nodes collection.
        /// </summary>
        /// <value>The nodes.</value>
        public XmlNodeList Nodes { get; set; }

        /// <summary>
        /// Gets or sets the collection of DLLs to be installed into the GAC.
        /// </summary>
        /// <value><see cref="Dictionary"/> of dlls.</value>
        public Dictionary<string, string> DllsToGac { get; set; }

        #endregion // Proeprties

        private const string _owner = "TelerikConfigFeature";
        #region Methods

        /// <summary>
        /// Makes required changes for web.config based on deployment type.
        /// </summary>
        /// <param name="deploymentType">Type of the deployment.</param>
        public void Deploy(DeploymentType deploymentType) {
            this.ModifyWebConfig(deploymentType);         
            //this.ModifyGac(deploymentType);
        }

        /// <summary>
        /// Modifies the GAC.
        /// </summary>
        /// <param name="deploymentType">Type of the deployment.</param>
        private void ModifyGac(DeploymentType deploymentType) {
            foreach (string key in this.DllsToGac.Keys)  {
                string assembly = this.DllsToGac[key] + key;
                Publish p = new Publish();
                if (deploymentType == DeploymentType.Deploy)
                    p.GacInstall(assembly);
                else
                    p.GacRemove(assembly);
            }
        }

        /// <summary>
        /// Modifies the web config.
        /// </summary>
        /// <param name="deploymentType">Type of the deployment.</param>
        private void ModifyWebConfig(DeploymentType deploymentType) {

            SPWebApplication webApplication = SPWebService.ContentService.WebApplications[this.WebApplicationId];
            if (deploymentType == DeploymentType.Deploy && webApplication!=null) {
                Collection<SPWebConfigModification> webConfigModifications = this.CreateWebConfigModifications();
                // Clears the SPWebConfigModification collection, in order to prevent appling of
                // earlier entered modifications.
                webApplication.WebConfigModifications.Clear();
                foreach (SPWebConfigModification webConfigModification in webConfigModifications) {
                    webApplication.WebConfigModifications.Add(webConfigModification);
                    /* if (deploymentType == DeploymentType.Deploy)
                         webApplication.WebConfigModifications.Add(webConfigModification);
                     else
                         webApplication.WebConfigModifications.Remove(webConfigModification); */
                }
            }
            else {

                if (webApplication != null) {

                    Collection<SPWebConfigModification> collection = webApplication.WebConfigModifications;
                    int _Count = collection.Count;
                    // Remove any modifications that were originally created by the owner.
                    for(int i=_Count-1;i>=0;i--) {
                    SPWebConfigModification configMod = collection[i];
                        if (configMod.Owner == _owner)
                        collection.Remove(configMod);
                    }
               }
            }
            // Applyes all modification to web.config.
            webApplication.Update();
            webApplication.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
            //webApplication.WebService.ApplyWebConfigModifications();
           // webApplication.Update();
        }

        /// <summary>
        /// Creates collection of the web config modifications, based on
        /// information from XML file.
        /// </summary>
        /// <returns><see cref="Collection"/> of <see cref="SPWebConfigModification"/></returns>
        private Collection<SPWebConfigModification> CreateWebConfigModifications() {
            Collection<SPWebConfigModification> webConfigModifications = new Collection<SPWebConfigModification>();

            foreach (XmlNode node in this.Nodes) {
                // Throws out comments.
                if (node.NodeType == XmlNodeType.Comment)
                    continue;

                SPWebConfigModification webConfigModification = new SPWebConfigModification();
                webConfigModification.Name = node.Attributes["Name"].Value;
                webConfigModification.Path = node.Attributes["Path"].Value;
                webConfigModification.Sequence = 0;
                webConfigModification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
                webConfigModification.Value = node.InnerXml;
                webConfigModification.Owner = _owner;
                webConfigModifications.Add(webConfigModification);
            }

            return webConfigModifications;
        }

        #endregion // Methods
    }
1

2 Answers 2

1

The documentation may say it is a best practice, but SPWebConfigModification is quite flacky and may render your SharePoint farm broken beyond repair. A (parted) SharePoint Master in our company recommended to stay away from SPWebConfigModification... SPWebConfigModification works okay on a single server (dev) SharePoint farm, but may unleash trouble on a multiserver farm.

In my current project (SharePoint 2007 portals), we have many, many additions to the SharePoint webapp web.configs (including ServiceModel thingies and extra compilation assembly registrations). This many changes and the inability for SPWebConfigModification API to be able to change the necessary sections of the web.config, we decided to supply the web.configs with the deployment package that must be copied over the existing web.configs in the SharePoint webapp IIS paths.

0

Thanks Guys,this code works fine on multiple server on farm it was nothing wrong with code it was some permission issue and it was taking to much time for timer job to finish.Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.