protected internal virtual void DeserializeElement(XmlReader reader, bool serializeCollectionKey) {
ConfigurationPropertyCollection props = Properties;
ConfigurationValue LockedAttributesList = null;
ConfigurationValue LockedAllExceptList = null;
ConfigurationValue LockedElementList = null;
ConfigurationValue LockedAllElementsExceptList = null;
bool ItemLockedLocally = false;
_bElementPresent = true;
ConfigurationElement defaultCollection = null;
ConfigurationProperty defaultCollectionProperty = props != null ? props.DefaultCollectionProperty : null;
if (defaultCollectionProperty != null) {
defaultCollection = (ConfigurationElement)this[defaultCollectionProperty];
}
// Process attributes
_elementTagName = reader.Name;
PropertySourceInfo rootInfo = new PropertySourceInfo(reader);
_values.SetValue(reader.Name, null, ConfigurationValueFlags.Modified, rootInfo);
_values.SetValue(DefaultCollectionPropertyName, defaultCollection, ConfigurationValueFlags.Modified, rootInfo);
if ((_lockedElementsList != null && (_lockedElementsList.Contains(reader.Name) ||
(_lockedElementsList.Contains(LockAll) && reader.Name != ElementTagName))) ||
(_lockedAllExceptElementsList != null && _lockedAllExceptElementsList.Count != 0 && !_lockedAllExceptElementsList.Contains(reader.Name)) ||
((_fItemLocked & ConfigurationValueFlags.Locked) != 0 && (_fItemLocked & ConfigurationValueFlags.Inherited) != 0)
) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_element_locked, reader.Name), reader);
}
if (reader.AttributeCount > 0) {
while (reader.MoveToNextAttribute()) {
String propertyName = reader.Name;
if ((_lockedAttributesList != null && (_lockedAttributesList.Contains(propertyName) || _lockedAttributesList.Contains(LockAll))) ||
(_lockedAllExceptAttributesList != null && !_lockedAllExceptAttributesList.Contains(propertyName))
) {
if (propertyName != LockAttributesKey && propertyName != LockAllAttributesExceptKey)
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_attribute_locked, propertyName), reader);
}
ConfigurationProperty prop = props != null ? props[propertyName] : null;
if (prop != null) {
if (serializeCollectionKey && !prop.IsKey) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_unrecognized_attribute, propertyName), reader);
}
_values.SetValue(propertyName,
DeserializePropertyValue(prop, reader),
ConfigurationValueFlags.Modified,
new PropertySourceInfo(reader));
} // if (deserializing a remove OR an add that does not handle optional attributes)
else if (propertyName == LockItemKey) {
try {
ItemLockedLocally = bool.Parse(reader.Value);
}
catch {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_invalid_boolean_attribute, propertyName), reader);
}
}
else if (propertyName == LockAttributesKey) {
LockedAttributesList = new ConfigurationValue(reader.Value, ConfigurationValueFlags.Default, new PropertySourceInfo(reader));
}
else if (propertyName == LockAllAttributesExceptKey) {
LockedAllExceptList = new ConfigurationValue(reader.Value, ConfigurationValueFlags.Default, new PropertySourceInfo(reader));
}
else if (propertyName == LockElementsKey) {
LockedElementList = new ConfigurationValue(reader.Value, ConfigurationValueFlags.Default, new PropertySourceInfo(reader));
}
else if (propertyName == LockAllElementsExceptKey) {
LockedAllElementsExceptList = new ConfigurationValue(reader.Value, ConfigurationValueFlags.Default, new PropertySourceInfo(reader));
}
else if (serializeCollectionKey || !OnDeserializeUnrecognizedAttribute(propertyName, reader.Value)) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_unrecognized_attribute, propertyName), reader);
}
}
}
reader.MoveToElement();
// Check for nested elements.
try {
HybridDictionary nodeFound = new HybridDictionary();
if (!reader.IsEmptyElement) {
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element) {
String propertyName = reader.Name;
CheckLockedElement(propertyName, null);
ConfigurationProperty prop = props != null ? props[propertyName] : null;
if (prop != null) {
if (typeof(ConfigurationElement).IsAssignableFrom(prop.Type)) {
if (nodeFound.Contains(propertyName))
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_element_cannot_have_multiple_child_elements, propertyName), reader);
nodeFound.Add(propertyName, propertyName);
ConfigurationElement childElement = (ConfigurationElement)this[prop];
childElement.DeserializeElement(reader, serializeCollectionKey);
// Validate the new element with the per-property Validator
// Note that the per-type validator for childElement has been already executed as part of Deserialize
ValidateElement(childElement, prop.Validator, false);
}
else {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_property_is_not_a_configuration_element, propertyName), reader);
}
}
else if (!OnDeserializeUnrecognizedElement(propertyName, reader)) {
// Let the default collection, if there is one, handle this node.
if (defaultCollection == null ||
!defaultCollection.OnDeserializeUnrecognizedElement(propertyName, reader)) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_unrecognized_element_name, propertyName), reader);
}
}
}
else if (reader.NodeType == XmlNodeType.EndElement) {
break;
}
else if ((reader.NodeType == XmlNodeType.CDATA) || (reader.NodeType == XmlNodeType.Text)) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_section_invalid_content), reader);
}
}
}
EnsureRequiredProperties(serializeCollectionKey);
// Call the per-type validator for this object
ValidateElement(this, null, false);
}
catch (ConfigurationException e) {
// Catch the generic message from deserialization and include line info if necessary
if (e.Filename == null || e.Filename.Length == 0)
throw new ConfigurationErrorsException(e.Message, reader); // give it some info
else
throw e;
}
if (ItemLockedLocally) {
SetLocked();
_fItemLocked = ConfigurationValueFlags.Locked;
}
if (LockedAttributesList != null) {
if (_lockedAttributesList == null)
_lockedAttributesList = new ConfigurationLockCollection(this, ConfigurationLockCollectionType.LockedAttributes);
foreach (string key in ParseLockedAttributes(LockedAttributesList, ConfigurationLockCollectionType.LockedAttributes)) {
if (!_lockedAttributesList.Contains(key))
_lockedAttributesList.Add(key, ConfigurationValueFlags.Default); // add the local copy
else
_lockedAttributesList.Add(key, ConfigurationValueFlags.Modified | ConfigurationValueFlags.Inherited); // add the local copy
}
}
if (LockedAllExceptList != null) {
ConfigurationLockCollection newCollection = ParseLockedAttributes(LockedAllExceptList, ConfigurationLockCollectionType.LockedExceptionList);
if (_lockedAllExceptAttributesList == null) {
_lockedAllExceptAttributesList = new ConfigurationLockCollection(this, ConfigurationLockCollectionType.LockedExceptionList, String.Empty, newCollection);
_lockedAllExceptAttributesList.ClearSeedList(); // Prevent the list from thinking this was set by a parent.
}
StringCollection intersectionCollection = IntersectLockCollections(_lockedAllExceptAttributesList, newCollection);
/*
if (intersectionCollection.Count == 0) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_empty_lock_attributes_except_effective,
LockAllAttributesExceptKey,
LockedAllExceptList.Value,
LockAttributesKey),
LockedAllExceptList.SourceInfo.FileName,
LockedAllExceptList.SourceInfo.LineNumber);
}
*/
_lockedAllExceptAttributesList.ClearInternal(false);
foreach (string key in intersectionCollection) {
_lockedAllExceptAttributesList.Add(key, ConfigurationValueFlags.Default);
}
}
if (LockedElementList != null) {
if (_lockedElementsList == null)
_lockedElementsList = new ConfigurationLockCollection(this, ConfigurationLockCollectionType.LockedElements);
ConfigurationLockCollection localLockedElementList = ParseLockedAttributes(LockedElementList, ConfigurationLockCollectionType.LockedElements);
ConfigurationElementCollection collection = null;
if (props.DefaultCollectionProperty != null) // this is not a collection but it may contain a default collection
{
collection = this[props.DefaultCollectionProperty] as ConfigurationElementCollection;
if (collection != null && collection._lockedElementsList == null)
collection._lockedElementsList = _lockedElementsList;
}
foreach (string key in localLockedElementList) {
if (!_lockedElementsList.Contains(key)) {
_lockedElementsList.Add(key, ConfigurationValueFlags.Default); // add the local copy
ConfigurationProperty propToLock = Properties[key];
if (propToLock != null && typeof(ConfigurationElement).IsAssignableFrom(propToLock.Type)) {
((ConfigurationElement)this[key]).SetLocked();
}
if (key == LockAll) {
foreach (ConfigurationProperty prop in Properties) {
if (!string.IsNullOrEmpty(prop.Name) &&
typeof(ConfigurationElement).IsAssignableFrom(prop.Type)) {
((ConfigurationElement)this[prop]).SetLocked();
}
}
}
}
}
}
if (LockedAllElementsExceptList != null) {
ConfigurationLockCollection newCollection = ParseLockedAttributes(LockedAllElementsExceptList, ConfigurationLockCollectionType.LockedElementsExceptionList);
if (_lockedAllExceptElementsList == null) {
_lockedAllExceptElementsList = new ConfigurationLockCollection(this, ConfigurationLockCollectionType.LockedElementsExceptionList, _elementTagName, newCollection);
_lockedAllExceptElementsList.ClearSeedList();
}
StringCollection intersectionCollection = IntersectLockCollections(_lockedAllExceptElementsList, newCollection);
ConfigurationElementCollection collection = null;
if (props.DefaultCollectionProperty != null) // this is not a collection but it may contain a default collection
{
collection = this[props.DefaultCollectionProperty] as ConfigurationElementCollection;
if (collection != null && collection._lockedAllExceptElementsList == null)
collection._lockedAllExceptElementsList = _lockedAllExceptElementsList;
}
_lockedAllExceptElementsList.ClearInternal(false);
foreach (string key in intersectionCollection) {
if (!_lockedAllExceptElementsList.Contains(key) || key == ElementTagName)
_lockedAllExceptElementsList.Add(key, ConfigurationValueFlags.Default); // add the local copy
}
foreach (ConfigurationProperty prop in Properties) {
if (!(string.IsNullOrEmpty(prop.Name) || _lockedAllExceptElementsList.Contains(prop.Name)) &&
typeof(ConfigurationElement).IsAssignableFrom(prop.Type)) {
((ConfigurationElement)this[prop]).SetLocked();
}
}
}
// Make sure default collections use the same lock element lists
if (defaultCollectionProperty != null) {
defaultCollection = (ConfigurationElement)this[defaultCollectionProperty];
if (_lockedElementsList == null) {
_lockedElementsList = new ConfigurationLockCollection(this, ConfigurationLockCollectionType.LockedElements);
}
defaultCollection._lockedElementsList = _lockedElementsList;
if (_lockedAllExceptElementsList == null) {
_lockedAllExceptElementsList = new ConfigurationLockCollection(this, ConfigurationLockCollectionType.LockedElementsExceptionList, reader.Name);
_lockedAllExceptElementsList.ClearSeedList();
}
defaultCollection._lockedAllExceptElementsList = _lockedAllExceptElementsList;
}
// This has to be the last thing to execute
PostDeserialize();
}