Modify web.config, Add <SafeContol>

May 9, 2008 at 5:43 PM
Edited May 9, 2008 at 5:46 PM
Hello,

Ted Pattison recommends ...

"If [your] modification is for adding a SafeControl element or modifying the Code Access Security Setting for a Web Part assembly, you should not be writing code to accomplish this. Instead, you should be updating the web.config file declaratively using SafeControl elements and CodeAccessSecurity elements inside the manifest.xml file within a solution package." -- http://blog.tedpattison.net/Lists/Posts/Post.aspx?List=80e51818%2D7b98%2D41d8%2Db313%2D955977ecd68f&ID=4

Since I am using WSPBuilder to control the creation of manifest.xml, how can I accomplish this? I want to instruct WSPBuiler to add a <safecontrol> entry for System.Data.OracleClient and other dlls as well. I do not want to write a feature for this task if possible.

Should I add the dll to my 80\Bin folder, or is there a better way that doesn't require copying the dll?
Since System.Data.OracleClient is already in the GAC, I really don't want to add it to 80\Bin either.

Thanks, RC
May 13, 2008 at 7:41 PM
Update: 
I found that using System.Data.OracleClient did not require an entry to <SafeControls>.  Rather it required an entry to assemblies.
<add assembly="System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

I decided to do this modification using the feature's FeatureActivated event.

    /// <summary>
    /// Handles activation, deactivation, installation and uninstallation events of the feature.
    /// </summary>
    /// <remarks>
    /// See reference: http://blog.tedpattison.net/Lists/Posts/Post.aspx?List=80e51818%2D7b98%2D41d8%2Db313%2D955977ecd68f&ID=4
    /// </remarks>
    public class FeatureReceiver : SPFeatureReceiver
    {
        private List<ModificationEntry> _modifications;

        /// <summary>
        /// Defines all the data required to make a single modification entry.
        /// </summary>
        private struct ModificationEntry
        {
            public string Name;
            public string XPath;
            public string Value;
            public SPWebConfigModification.SPWebConfigModificationType ModType;
           
            public ModificationEntry(string name, string xPath, string value,
                   SPWebConfigModification.SPWebConfigModificationType modType)
            {
                this.Name = name;
                this.XPath = xPath;
                this.Value = value;
                this.ModType = modType;
            }
        }

        public FeatureReceiver()
        {
            // Initialize the modifications that this feature will use.
            _modifications = new List<ModificationEntry>();

            _modifications.Add(new ModificationEntry(
                           @"add [@assembly='Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c']",
                           "configuration/system.web/compilation/assemblies",
                           @"<add assembly=""Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"" />",
                           SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode));

            _modifications.Add(new ModificationEntry(
                           @"add [@assembly='System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089']",
                           "configuration/system.web/compilation/assemblies",
                           @"<add assembly=""System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"" />",
                           SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode));
        }

        private SPWebConfigModification CreateModification(ModificationEntry modEntry)
        {
            var modification = new SPWebConfigModification(modEntry.Name, modEntry.XPath);
            modification.Owner = this.GetType().FullName;
            modification.Sequence = 0;
            modification.Type = modEntry.ModType;
            modification.Value = modEntry.Value;
            return modification;
        }

        /// <summary>
        /// Modifies web.config when the feature is activated.
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            // Get the target web application from the feature.
            var site = properties.Feature.Parent as SPSite;
            var webApp = site.WebApplication;

            // Add all modifications.
            foreach (ModificationEntry modEntry in _modifications)
            {
                webApp.WebConfigModifications.Add(CreateModification(modEntry));
            }

            // Apply them via the farm's web service.
            webApp.WebService.ApplyWebConfigModifications();
        }

        /// <summary>
        /// Modifies web.config when the feature is deactivated.
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            // Get the target web application from the feature.
            var site = properties.Feature.Parent as SPSite;
            var webApp = site.WebApplication;

            // Remove all modifications.
            foreach (ModificationEntry modEntry in _modifications)
            {
                webApp.WebConfigModifications.Remove(CreateModification(modEntry));
            }

            // Apply them via the farm's web service.
            webApp.WebService.ApplyWebConfigModifications();
        }

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { /* no op */ }
        public override void FeatureInstalled(SPFeatureReceiverProperties properties) { /* no op */ }
    }

Hope that helps someone.  RC
Mar 26, 2009 at 10:20 AM
Edited Mar 26, 2009 at 10:26 AM

Hi

I have SharePoint weapplication set on port  80 and then I have extended site to port 81on intranet domain

I have created feature(scope of the feature is anyamongst WebApplication/Site/Web)  toupdate  the web.Config file 

Now when I am trying to update the web.config file usingthis feature it is automatically updating config file on both sites i.e.  80 and 81 

Here my requirement is to update only site 80 not 81 

May I able to do that 

One more problem is when I am deactivating feature itremoves  configuration form site 80 notfrom 81 

Any help in this regard will be appreciated

Here my requirement is to update only site 80 not 81

May I able to do that ?

One more problem is when I am deactivating feature itremoves  configuration form site 80 notfrom 81

Any help in this regard will be appreciated

Mar 26, 2009 at 12:49 PM
I'm sorry I can't help.  Our team gave up on Sharepoint development after about 5 months of frustrating debugging and deployment experiences.  It was an awful platform (IMO), but I hear things will improve greatly in VS 2010.

Good luck to you.  I hope someone else can help.