private object Deserialize() { object value = null; // Attempt 1: Try creating from SerializedValue if (SerializedValue != null) { bool throwBinaryFormatterDeprecationException = false; try { if (SerializedValue is string) { value = GetObjectFromString(Property.PropertyType, Property.SerializeAs, (string)SerializedValue); } else { if (SettingsProperty.EnableUnsafeBinaryFormatterInPropertyValueSerialization) { using (MemoryStream ms = new MemoryStream((byte[])SerializedValue)) { #pragma warning disable SYSLIB0011 // BinaryFormatter serialization is obsolete and should not be used. value = (new BinaryFormatter()).Deserialize(ms); #pragma warning restore SYSLIB0011 } } else { throwBinaryFormatterDeprecationException = true; } } } catch (Exception exception) { try { if (IsHostedInAspnet()) { object[] args = new object[] { Property, this, exception }; const string webBaseEventTypeName = "System.Web.Management.WebBaseEvent, System.Web"; Type type = Type.GetType(webBaseEventTypeName, true); type.InvokeMember("RaisePropertyDeserializationWebErrorEvent", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, args, CultureInfo.InvariantCulture); } } catch { } } if (throwBinaryFormatterDeprecationException) { throw new NotSupportedException(Obsoletions.BinaryFormatterMessage); } if (value != null && !Property.PropertyType.IsAssignableFrom(value.GetType())) // is it the correct type { value = null; } } // Attempt 2: Try creating from default value if (value == null) { UsingDefaultValue = true; if (Property.DefaultValue == null || Property.DefaultValue.ToString() == "[null]") { if (Property.PropertyType.IsValueType) { return(TypeUtil.CreateInstance(Property.PropertyType)); } else { return(null); } } if (!(Property.DefaultValue is string)) { value = Property.DefaultValue; } else { try { value = GetObjectFromString(Property.PropertyType, Property.SerializeAs, (string)Property.DefaultValue); } catch (Exception e) { throw new ArgumentException(SR.Format(SR.Could_not_create_from_default_value, Property.Name, e.Message)); } } if (value != null && !Property.PropertyType.IsAssignableFrom(value.GetType())) // is it the correct type { throw new ArgumentException(SR.Format(SR.Could_not_create_from_default_value_2, Property.Name)); } } // Attempt 3: Create via the parameterless constructor if (value == null) { if (Property.PropertyType == typeof(string)) { value = string.Empty; } else { try { value = TypeUtil.CreateInstance(Property.PropertyType); } catch { } } } return(value); }
/// <summary> /// Creates a SettingsProperty object using the metadata on the given property /// and returns it. /// </summary> private SettingsProperty CreateSetting(PropertyInfo propertyInfo) { // Initialization method - // be careful not to access properties here to prevent stack overflow. object[] attributes = propertyInfo.GetCustomAttributes(false); SettingsProperty settingsProperty = new SettingsProperty(Initializer); bool explicitSerialize = _explicitSerializeOnClass; settingsProperty.Name = propertyInfo.Name; settingsProperty.PropertyType = propertyInfo.PropertyType; for (int i = 0; i < attributes.Length; i++) { Attribute attribute = attributes[i] as Attribute; if (attribute == null) { continue; } if (attribute is DefaultSettingValueAttribute) { settingsProperty.DefaultValue = ((DefaultSettingValueAttribute)attribute).Value; } else if (attribute is ReadOnlyAttribute) { settingsProperty.IsReadOnly = true; } else if (attribute is SettingsProviderAttribute) { string providerTypeName = ((SettingsProviderAttribute)attribute).ProviderTypeName; Type providerType = Type.GetType(providerTypeName); if (providerType == null) { throw new ConfigurationErrorsException(SR.Format(SR.ProviderTypeLoadFailed, providerTypeName)); } SettingsProvider settingsProvider = TypeUtil.CreateInstance(providerType) as SettingsProvider; if (settingsProvider == null) { throw new ConfigurationErrorsException(SR.Format(SR.ProviderInstantiationFailed, providerTypeName)); } settingsProvider.Initialize(null, null); settingsProvider.ApplicationName = ConfigurationManagerInternalFactory.Instance.ExeProductName; // See if we already have a provider of the same name in our collection. If so, // re-use the existing instance, since we cannot have multiple providers of the same name. SettingsProvider existing = _providers[settingsProvider.Name]; if (existing != null) { settingsProvider = existing; } settingsProperty.Provider = settingsProvider; } else if (attribute is SettingsSerializeAsAttribute) { settingsProperty.SerializeAs = ((SettingsSerializeAsAttribute)attribute).SerializeAs; explicitSerialize = true; } else { // This isn't an attribute we care about, so simply pass it on // to the SettingsProvider. // // NOTE: The key is the type. So if an attribute was found at class // level and also property level, the latter overrides the former // for a given setting. This is exactly the behavior we want. settingsProperty.Attributes.Add(attribute.GetType(), attribute); } } if (!explicitSerialize) { // Serialization method was not explicitly attributed. TypeConverter tc = TypeDescriptor.GetConverter(propertyInfo.PropertyType); if (tc.CanConvertTo(typeof(string)) && tc.CanConvertFrom(typeof(string))) { // We can use string settingsProperty.SerializeAs = SettingsSerializeAs.String; } else { // Fallback is Xml settingsProperty.SerializeAs = SettingsSerializeAs.Xml; } } return(settingsProperty); }