The Labs \ Source Viewer \ SSCLI \ System.Configuration \ SectionInformation

  1. //------------------------------------------------------------------------------
  2. // <copyright file="SectionInformation.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Configuration
  16. {
  17.     using System;
  18.     using System.Collections.Specialized;
  19.     using System.Configuration.Internal;
  20.     using System.IO;
  21.     using System.Reflection;
  22.     using System.Security;
  23.     using System.Text;
  24.     using System.Xml;
  25.     using System.Globalization;
  26.    
  27.     public sealed class SectionInformation
  28.     {
  29.         // Flags
  30.         private const int Flag_Attached = 1;
  31.         private const int Flag_Declared = 2;
  32.         private const int Flag_DeclarationRequired = 4;
  33.         private const int Flag_AllowLocation = 8;
  34.         private const int Flag_RestartOnExternalChanges = 16;
  35.         private const int Flag_RequirePermission = 32;
  36.         private const int Flag_LocationLocked = 64;
  37.         private const int Flag_AllowOverride = 128;
  38.         private const int Flag_InheritInChildApps = 256;
  39.         private const int Flag_IsParentSection = 512;
  40.         private const int Flag_Removed = 1024;
  41.         private const int Flag_ProtectionProviderDetermined = 2048;
  42.         private const int Flag_ForceSave = 4096;
  43.         private const int Flag_IsUndeclared = 8192;
  44.         private const int Flag_AllowExeDefinitionModified = 65536;
  45.         private const int Flag_AllowDefinitionModified = 131072;
  46.         private const int Flag_ConfigSourceModified = 262144;
  47.         private const int Flag_ProtectionProviderModified = 524288;
  48.        
  49.         private ConfigurationSection _configurationSection;
  50.         private SafeBitVector32 _flags;
  51.         private SimpleBitVector32 _modifiedFlags;
  52.         private ConfigurationAllowDefinition _allowDefinition;
  53.         private ConfigurationAllowExeDefinition _allowExeDefinition;
  54.         private MgmtConfigurationRecord _configRecord;
  55.         private string _configKey;
  56.         private string _group;
  57.         private string _name;
  58.         private string _typeName;
  59.         private string _rawXml;
  60.         private string _configSource;
  61.         private string _configSourceStreamName;
  62.         private ProtectedConfigurationProvider _protectionProvider;
  63.         private string _protectionProviderName;
  64.        
  65.         //
  66.         // Constructor
  67.         //
  68.         internal SectionInformation(ConfigurationSection associatedConfigurationSection)
  69.         {
  70.             _configKey = String.Empty;
  71.             _group = String.Empty;
  72.             _name = String.Empty;
  73.            
  74.             _configurationSection = associatedConfigurationSection;
  75.             _allowDefinition = ConfigurationAllowDefinition.Everywhere;
  76.             _allowExeDefinition = ConfigurationAllowExeDefinition.MachineToApplication;
  77.            
  78.             _flags[Flag_AllowLocation] = true;
  79.             _flags[Flag_RestartOnExternalChanges] = true;
  80.             _flags[Flag_RequirePermission] = true;
  81.             _flags[Flag_AllowOverride] = true;
  82.             _flags[Flag_InheritInChildApps] = true;
  83.             _flags[Flag_ForceSave] = false;
  84.            
  85.             _modifiedFlags = new SimpleBitVector32();
  86.         }
  87.        
  88.         internal void ResetModifiedFlags()
  89.         {
  90.             _modifiedFlags = new SimpleBitVector32();
  91.         }
  92.        
  93.         internal bool IsModifiedFlags()
  94.         {
  95.             return (_modifiedFlags.Data != 0);
  96.         }
  97.         // for instantiation of a ConfigurationSection from GetConfig
  98.         internal void AttachToConfigurationRecord(MgmtConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord)
  99.         {
  100.             SetRuntimeConfigurationInformation(configRecord, factoryRecord, sectionRecord);
  101.             _configRecord = configRecord;
  102.         }
  103.        
  104.         internal void SetRuntimeConfigurationInformation(BaseConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord)
  105.         {
  106.             _flags[Flag_Attached] = true;
  107.            
  108.             // factory info
  109.             _configKey = factoryRecord.ConfigKey;
  110.             _group = factoryRecord.Group;
  111.             _name = factoryRecord.Name;
  112.             _typeName = factoryRecord.FactoryTypeName;
  113.             _allowDefinition = factoryRecord.AllowDefinition;
  114.             _allowExeDefinition = factoryRecord.AllowExeDefinition;
  115.             _flags[Flag_AllowLocation] = factoryRecord.AllowLocation;
  116.             _flags[Flag_RestartOnExternalChanges] = factoryRecord.RestartOnExternalChanges;
  117.             _flags[Flag_RequirePermission] = factoryRecord.RequirePermission;
  118.            
  119.             if (factoryRecord.IsUndeclared) {
  120.                 _flags[Flag_IsUndeclared] = true;
  121.                 _flags[Flag_Declared] = false;
  122.                 _flags[Flag_DeclarationRequired] = false;
  123.             }
  124.             else {
  125.                 _flags[Flag_IsUndeclared] = false;
  126.                 _flags[Flag_Declared] = configRecord.GetFactoryRecord(factoryRecord.ConfigKey, false) != null;
  127.                 _flags[Flag_DeclarationRequired] = configRecord.IsRootDeclaration(factoryRecord.ConfigKey, false);
  128.             }
  129.            
  130.             // section info
  131.             _flags[Flag_LocationLocked] = sectionRecord.Locked;
  132.            
  133.             if (sectionRecord.HasFileInput) {
  134.                 SectionInput fileInput = sectionRecord.FileInput;
  135.                
  136.                 _flags[Flag_ProtectionProviderDetermined] = fileInput.IsProtectionProviderDetermined;
  137.                 _protectionProvider = fileInput.ProtectionProvider;
  138.                
  139.                 SectionXmlInfo sectionXmlInfo = fileInput.SectionXmlInfo;
  140.                
  141.                 _configSource = sectionXmlInfo.ConfigSource;
  142.                 _configSourceStreamName = sectionXmlInfo.ConfigSourceStreamName;
  143.                 _flags[Flag_AllowOverride] = !sectionXmlInfo.LockChildren;
  144.                 _flags[Flag_InheritInChildApps] = !sectionXmlInfo.SkipInChildApps;
  145.                 _protectionProviderName = sectionXmlInfo.ProtectionProviderName;
  146.             }
  147.             else {
  148.                 _flags[Flag_ProtectionProviderDetermined] = false;
  149.                 _protectionProvider = null;
  150.             }
  151.            
  152.             // element context information
  153.             _configurationSection.AssociateContext(configRecord);
  154.         }
  155.        
  156.         internal void DetachFromConfigurationRecord()
  157.         {
  158.             RevertToParent();
  159.             _flags[Flag_Attached] = false;
  160.             _configRecord = null;
  161.         }
  162.        
  163.         private bool IsRuntime {
  164.             get { return (_flags[Flag_Attached]) && (_configRecord == null); }
  165.         }
  166.        
  167.         internal bool Attached {
  168.             get { return _flags[Flag_Attached]; }
  169.         }
  170.        
  171.         private void VerifyDesigntime()
  172.         {
  173.             if (IsRuntime) {
  174.                 throw new InvalidOperationException(SR.GetString(SR.Config_operation_not_runtime));
  175.             }
  176.         }
  177.        
  178.         private void VerifyIsAttachedToConfigRecord()
  179.         {
  180.             if (_configRecord == null) {
  181.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_when_not_attached));
  182.             }
  183.         }
  184.        
  185.         // VerifyIsEditable
  186.         //
  187.         // Verify the section is Editable.
  188.         // It may not be editable for the following reasons:
  189.         // - We are in Runtime mode, not Design time
  190.         // - The section is not attached to a _configRecord.
  191.         // - We are locked (ie. allowOveride = false )
  192.         // - We are a parent section (ie. Retrieved from GetParentSection)
  193.         //
  194.         internal void VerifyIsEditable()
  195.         {
  196.             VerifyDesigntime();
  197.             if (IsLocked) {
  198.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_when_locked));
  199.             }
  200.            
  201.             if (_flags[Flag_IsParentSection]) {
  202.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_parentsection));
  203.             }
  204.            
  205.             if (!_flags[Flag_AllowLocation] && (_configRecord != null) && (_configRecord.IsLocationConfig)) {
  206.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_when_location_locked));
  207.             }
  208.         }
  209.        
  210.         // VerifyNotParentSection
  211.         //
  212.         // Verify that this is not a parent section
  213.         //
  214.         private void VerifyNotParentSection()
  215.         {
  216.             if (_flags[Flag_IsParentSection]) {
  217.                 throw new InvalidOperationException(SR.GetString(SR.Config_configsection_parentnotvalid));
  218.             }
  219.         }
  220.        
  221.         // VerifySupportsLocation
  222.         //
  223.         // Verify that we support the location tag. This is true either
  224.         // in machine.config, or in any place for the web config system
  225.         //
  226.         private void VerifySupportsLocation()
  227.         {
  228.             if ((_configRecord != null) && !_configRecord.RecordSupportsLocation) {
  229.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_locationattriubtes));
  230.             }
  231.         }
  232.        
  233.         internal void VerifyIsEditableFactory()
  234.         {
  235.             if (_configRecord != null && _configRecord.IsLocationConfig) {
  236.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_in_location_config));
  237.             }
  238.            
  239.             // Can't edit factory if the section is built-in
  240.             if (BaseConfigurationRecord.IsImplicitSection(ConfigKey)) {
  241.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_when_it_is_implicit));
  242.             }
  243.            
  244.             // Can't edit undeclared section
  245.             if (_flags[Flag_IsUndeclared]) {
  246.                 throw new InvalidOperationException(SR.GetString(SR.Config_cannot_edit_configurationsection_when_it_is_undeclared));
  247.             }
  248.         }
  249.        
  250.         internal string ConfigKey {
  251.             get { return _configKey; }
  252.         }
  253.        
  254.         internal bool Removed {
  255.             get { return _flags[Flag_Removed]; }
  256.             set { _flags[Flag_Removed] = value; }
  257.         }
  258.        
  259.         private FactoryRecord FindParentFactoryRecord(bool permitErrors)
  260.         {
  261.             FactoryRecord factoryRecord = null;
  262.            
  263.             if (_configRecord != null && !_configRecord.Parent.IsRootConfig) {
  264.                 factoryRecord = _configRecord.Parent.FindFactoryRecord(_configKey, permitErrors);
  265.             }
  266.            
  267.             return factoryRecord;
  268.         }
  269.        
  270.         //
  271.         // public properties and methods
  272.         //
  273.         public string SectionName {
  274.             get { return _configKey; }
  275.         }
  276.        
  277.         public string Name {
  278.             get { return _name; }
  279.         }
  280.        
  281.         public ConfigurationAllowDefinition AllowDefinition {
  282.             get { return _allowDefinition; }
  283.             set {
  284.                 VerifyIsEditable();
  285.                 VerifyIsEditableFactory();
  286.                
  287.                 // allow AllowDefinition to be different from current type,
  288.                 // so long as it doesn't conflict with a type already defined
  289.                 FactoryRecord factoryRecord = FindParentFactoryRecord(false);
  290.                 if (factoryRecord != null && factoryRecord.AllowDefinition != value) {
  291.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, _configKey));
  292.                 }
  293.                
  294.                 _allowDefinition = value;
  295.                 _modifiedFlags[Flag_AllowDefinitionModified] = true;
  296.             }
  297.         }
  298.        
  299.         internal bool AllowDefinitionModified {
  300.             get { return _modifiedFlags[Flag_AllowDefinitionModified]; }
  301.         }
  302.        
  303.         public ConfigurationAllowExeDefinition AllowExeDefinition {
  304.             get { return _allowExeDefinition; }
  305.             set {
  306.                 VerifyIsEditable();
  307.                 VerifyIsEditableFactory();
  308.                
  309.                 // allow AllowDefinition to be different from current type,
  310.                 // so long as it doesn't conflict with a type already defined
  311.                 FactoryRecord factoryRecord = FindParentFactoryRecord(false);
  312.                 if (factoryRecord != null && factoryRecord.AllowExeDefinition != value) {
  313.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, _configKey));
  314.                 }
  315.                
  316.                 _allowExeDefinition = value;
  317.                 _modifiedFlags[Flag_AllowExeDefinitionModified] = true;
  318.             }
  319.         }
  320.        
  321.         internal bool AllowExeDefinitionModified {
  322.             get { return _modifiedFlags[Flag_AllowExeDefinitionModified]; }
  323.         }
  324.        
  325.         public bool AllowLocation {
  326.             get { return _flags[Flag_AllowLocation]; }
  327.             set {
  328.                 VerifyIsEditable();
  329.                 VerifyIsEditableFactory();
  330.                
  331.                 // allow AllowLocation to be different from current type,
  332.                 // so long as it doesn't conflict with a type already defined
  333.                 FactoryRecord factoryRecord = FindParentFactoryRecord(false);
  334.                 if (factoryRecord != null && factoryRecord.AllowLocation != value) {
  335.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, _configKey));
  336.                 }
  337.                
  338.                 _flags[Flag_AllowLocation] = value;
  339.                 _modifiedFlags[Flag_AllowLocation] = true;
  340.             }
  341.         }
  342.        
  343.         internal bool AllowLocationModified {
  344.             get { return _modifiedFlags[Flag_AllowLocation]; }
  345.         }
  346.        
  347.         public bool AllowOverride {
  348.             get { return _flags[Flag_AllowOverride]; }
  349.             set {
  350.                 VerifyIsEditable();
  351.                 VerifySupportsLocation();
  352.                 _flags[Flag_AllowOverride] = value;
  353.                 _modifiedFlags[Flag_AllowOverride] = true;
  354.             }
  355.         }
  356.        
  357.        
  358.         // LocationAttributesAreDefault
  359.         //
  360.         // Are the location attributes for this section set to the
  361.         // default settings?
  362.         //
  363.         internal bool LocationAttributesAreDefault {
  364.             get { return ((_flags[Flag_AllowOverride] == true) && (_flags[Flag_InheritInChildApps] == true)); }
  365.         }
  366.        
  367.         public string ConfigSource {
  368.             get {
  369.                 if (_configSource != null) {
  370.                     return _configSource;
  371.                 }
  372.                 else {
  373.                     return String.Empty;
  374.                 }
  375.             }
  376.            
  377.             set {
  378.                 string configSource;
  379.                
  380.                 VerifyIsEditable();
  381.                
  382.                 if (!String.IsNullOrEmpty(value)) {
  383.                     configSource = BaseConfigurationRecord.NormalizeConfigSource(value, null);
  384.                 }
  385.                 else {
  386.                     configSource = null;
  387.                 }
  388.                
  389.                 // return early if there is no change
  390.                 if (configSource == _configSource)
  391.                     return;
  392.                
  393.                 if (_configRecord != null) {
  394.                     _configRecord.ChangeConfigSource(this, _configSource, _configSourceStreamName, configSource);
  395.                 }
  396.                
  397.                 _configSource = configSource;
  398.                 _modifiedFlags[Flag_ConfigSourceModified] = true;
  399.             }
  400.         }
  401.        
  402.         internal bool ConfigSourceModified {
  403.             get { return _modifiedFlags[Flag_ConfigSourceModified]; }
  404.         }
  405.        
  406.         internal string ConfigSourceStreamName {
  407.             get { return _configSourceStreamName; }
  408.            
  409.             set { _configSourceStreamName = value; }
  410.         }
  411.        
  412.         public bool InheritInChildApplications {
  413.             get { return _flags[Flag_InheritInChildApps]; }
  414.             set {
  415.                 VerifyIsEditable();
  416.                 VerifySupportsLocation();
  417.                 _flags[Flag_InheritInChildApps] = value;
  418.             }
  419.         }
  420.        
  421.         // True if the section is declared at the current level
  422.         public bool IsDeclared {
  423.             get {
  424.                 VerifyNotParentSection();
  425.                
  426.                 return _flags[Flag_Declared];
  427.             }
  428.         }
  429.        
  430.         // IsDeclarationRequired
  431.         //
  432.         // Is the Declaration Required. It is required if it is not set
  433.         // in a parent, or the parent entry does not have the type
  434.         //
  435.         public bool IsDeclarationRequired {
  436.             get {
  437.                 VerifyNotParentSection();
  438.                
  439.                 return _flags[Flag_DeclarationRequired];
  440.             }
  441.         }
  442.        
  443.         // Force the section declaration to be written out during Save.
  444.         public void ForceDeclaration()
  445.         {
  446.             ForceDeclaration(true);
  447.         }
  448.        
  449.         // If force==false, it actually means don't declare it at
  450.         // the current level.
  451.         public void ForceDeclaration(bool force)
  452.         {
  453.             VerifyIsEditable();
  454.            
  455.             if ((force == false) && _flags[Flag_DeclarationRequired]) {
  456.                 // Since it is required, we can not remove it
  457.             }
  458.             else {
  459.                 if (force == true && BaseConfigurationRecord.IsImplicitSection(SectionName)) {
  460.                     throw new ConfigurationErrorsException(SR.GetString(SR.Cannot_declare_or_remove_implicit_section));
  461.                 }
  462.                
  463.                 if (force == true && _flags[Flag_IsUndeclared]) {
  464.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_cannot_edit_configurationsection_when_it_is_undeclared));
  465.                 }
  466.                
  467.                 _flags[Flag_Declared] = force;
  468.             }
  469.         }
  470.        
  471.         // IsDefinitionAllowed
  472.         //
  473.         // Is the Definition Allowed at this point. This is all depending
  474.         // on the Definition that is allowed, and what context we are
  475.         // writing the file
  476.         //
  477.         private bool IsDefinitionAllowed {
  478.             get {
  479.                 if (_configRecord == null) {
  480.                     return true;
  481.                 }
  482.                 else {
  483.                     return _configRecord.IsDefinitionAllowed(_allowDefinition, _allowExeDefinition);
  484.                 }
  485.             }
  486.         }
  487.        
  488.         public bool IsLocked {
  489.             get { return _flags[Flag_LocationLocked] || !IsDefinitionAllowed || _configurationSection.ElementInformation.IsLocked; }
  490.         }
  491.        
  492.         public bool IsProtected {
  493.             get { return (ProtectionProvider != null); }
  494.         }
  495.        
  496.         public ProtectedConfigurationProvider ProtectionProvider {
  497.             get {
  498.                 if (!_flags[Flag_ProtectionProviderDetermined] && _configRecord != null) {
  499.                     _protectionProvider = _configRecord.GetProtectionProviderFromName(_protectionProviderName, false);
  500.                     _flags[Flag_ProtectionProviderDetermined] = true;
  501.                 }
  502.                
  503.                 return _protectionProvider;
  504.             }
  505.         }
  506.        
  507.         // method to cause a section to be protected using the specified provider
  508.         public void ProtectSection(string protectionProvider)
  509.         {
  510.             ProtectedConfigurationProvider protectedConfigurationProvider = null;
  511.            
  512.             VerifyIsEditable();
  513.            
  514.             // Do not encrypt sections that will be read by a native reader.
  515.             // These sections are be marked with allowLocation=false.
  516.             // Also, the configProtectedData section cannot be encrypted!
  517.             if (!AllowLocation || _configKey == BaseConfigurationRecord.RESERVED_SECTION_PROTECTED_CONFIGURATION) {
  518.                 throw new InvalidOperationException(SR.GetString(SR.Config_not_allowed_to_encrypt_this_section));
  519.             }
  520.            
  521.             if (_configRecord != null) {
  522.                 if (String.IsNullOrEmpty(protectionProvider)) {
  523.                     protectionProvider = _configRecord.DefaultProviderName;
  524.                 }
  525.                
  526.                 protectedConfigurationProvider = _configRecord.GetProtectionProviderFromName(protectionProvider, true);
  527.             }
  528.             else {
  529.                 throw new InvalidOperationException(SR.GetString(SR.Must_add_to_config_before_protecting_it));
  530.             }
  531.            
  532.             _protectionProviderName = protectionProvider;
  533.             _protectionProvider = protectedConfigurationProvider;
  534.            
  535.             _flags[Flag_ProtectionProviderDetermined] = true;
  536.             _modifiedFlags[Flag_ProtectionProviderModified] = true;
  537.         }
  538.        
  539.         public void UnprotectSection()
  540.         {
  541.             VerifyIsEditable();
  542.            
  543.             _protectionProvider = null;
  544.             _protectionProviderName = null;
  545.             _flags[Flag_ProtectionProviderDetermined] = true;
  546.             _modifiedFlags[Flag_ProtectionProviderModified] = true;
  547.         }
  548.        
  549.         internal string ProtectionProviderName {
  550.             get { return _protectionProviderName; }
  551.         }
  552.        
  553.         public bool RestartOnExternalChanges {
  554.             get { return _flags[Flag_RestartOnExternalChanges]; }
  555.             set {
  556.                 VerifyIsEditable();
  557.                 VerifyIsEditableFactory();
  558.                
  559.                 // allow RestartOnExternalChanges to be different from current type,
  560.                 // so long as it doesn't conflict with a type already defined
  561.                 FactoryRecord factoryRecord = FindParentFactoryRecord(false);
  562.                 if (factoryRecord != null && factoryRecord.RestartOnExternalChanges != value) {
  563.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, _configKey));
  564.                 }
  565.                
  566.                 _flags[Flag_RestartOnExternalChanges] = value;
  567.                 _modifiedFlags[Flag_RestartOnExternalChanges] = true;
  568.             }
  569.         }
  570.        
  571.         internal bool RestartOnExternalChangesModified {
  572.             get { return _modifiedFlags[Flag_RestartOnExternalChanges]; }
  573.         }
  574.        
  575.         public bool RequirePermission {
  576.             get { return _flags[Flag_RequirePermission]; }
  577.             set {
  578.                 VerifyIsEditable();
  579.                 VerifyIsEditableFactory();
  580.                
  581.                 // allow RequirePermission to be different from current type,
  582.                 // so long as it doesn't conflict with a type already defined
  583.                 FactoryRecord factoryRecord = FindParentFactoryRecord(false);
  584.                 if (factoryRecord != null && factoryRecord.RequirePermission != value) {
  585.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, _configKey));
  586.                 }
  587.                
  588.                 _flags[Flag_RequirePermission] = value;
  589.                 _modifiedFlags[Flag_RequirePermission] = true;
  590.             }
  591.         }
  592.        
  593.         internal bool RequirePermissionModified {
  594.             get { return _modifiedFlags[Flag_RequirePermission]; }
  595.         }
  596.        
  597.        
  598.         public string Type {
  599.             get { return _typeName; }
  600.             set {
  601.                 if (String.IsNullOrEmpty(value)) {
  602.                     throw ExceptionUtil.PropertyNullOrEmpty("Type");
  603.                 }
  604.                
  605.                 VerifyIsEditable();
  606.                 VerifyIsEditableFactory();
  607.                
  608.                 // allow type to be different from current type,
  609.                 // so long as it doesn't conflict with a type already defined
  610.                 FactoryRecord factoryRecord = FindParentFactoryRecord(false);
  611.                 if (factoryRecord != null) {
  612.                     IInternalConfigHost host = null;
  613.                     if (_configRecord != null) {
  614.                         host = _configRecord.Host;
  615.                     }
  616.                    
  617.                     if (!factoryRecord.IsEquivalentType(host, value)) {
  618.                         throw new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, _configKey));
  619.                     }
  620.                 }
  621.                
  622.                 _typeName = value;
  623.             }
  624.         }
  625.        
  626.         public ConfigurationSection GetParentSection()
  627.         {
  628.             VerifyDesigntime();
  629.            
  630.             if (_flags[Flag_IsParentSection]) {
  631.                 throw new InvalidOperationException(SR.GetString(SR.Config_getparentconfigurationsection_first_instance));
  632.             }
  633.            
  634.             // if a users create a configsection with : sectionType sec = new sectionType();
  635.             // the config record will be null. Return null for the parent in this case.
  636.             ConfigurationSection ancestor = null;
  637.             if (_configRecord != null) {
  638.                 ancestor = _configRecord.FindAndCloneImmediateParentSection(_configurationSection);
  639.                 if (ancestor != null) {
  640.                     ancestor.SectionInformation._flags[Flag_IsParentSection] = true;
  641.                     ancestor.SetReadOnly();
  642.                 }
  643.             }
  644.            
  645.             return ancestor;
  646.         }
  647.        
  648.         public string GetRawXml()
  649.         {
  650.             VerifyDesigntime();
  651.             VerifyNotParentSection();
  652.            
  653.             if (RawXml != null) {
  654.                 return RawXml;
  655.             }
  656.             else if (_configRecord != null) {
  657.                 return _configRecord.GetRawXml(_configKey);
  658.             }
  659.             else {
  660.                 return null;
  661.             }
  662.         }
  663.        
  664.         public void SetRawXml(string rawXml)
  665.         {
  666.             VerifyIsEditable();
  667.            
  668.             if (_configRecord != null) {
  669.                 _configRecord.SetRawXml(_configurationSection, rawXml);
  670.             }
  671.             else {
  672.                 RawXml = (String.IsNullOrEmpty(rawXml)) ? null : rawXml;
  673.             }
  674.         }
  675.        
  676.         internal string RawXml {
  677.             get { return _rawXml; }
  678.            
  679.             set { _rawXml = value; }
  680.         }
  681.        
  682.         // True if the section will be serialized to the current hierarchy level, regardless of
  683.         // ConfigurationSaveMode.
  684.         public bool ForceSave {
  685.             get { return _flags[Flag_ForceSave]; }
  686.             set {
  687.                 VerifyIsEditable();
  688.                
  689.                 _flags[Flag_ForceSave] = value;
  690.             }
  691.         }
  692.        
  693.         public void RevertToParent()
  694.         {
  695.             VerifyIsEditable();
  696.             VerifyIsAttachedToConfigRecord();
  697.            
  698.             _configRecord.RevertToParent(_configurationSection);
  699.         }
  700.        
  701.     }
  702. }

Developer Fusion