1 //------------------------------------------------------------------------------
2 // <copyright file="SettingsPropertyValue.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Configuration {
8 using System.Collections;
9 using System.Collections.Specialized;
10 using System.Runtime.Serialization;
11 using System.Configuration.Provider;
12 using System.Globalization;
14 using System.Runtime.Serialization.Formatters.Binary;
15 using System.Xml.Serialization;
16 using System.ComponentModel;
17 using System.Security.Permissions;
18 using System.Reflection;
19 using System.Runtime.Versioning;
21 //////////////////////////////////////////////////////////////////////////////////
22 //////////////////////////////////////////////////////////////////////////////////
23 public class SettingsPropertyValue
25 public string Name { get { return _Property.Name; } }
26 public bool IsDirty { get { return _IsDirty; } set { _IsDirty = value; }}
27 public SettingsProperty Property { get { return _Property; } }
29 public bool UsingDefaultValue { get { return _UsingDefaultValue; } }
31 public SettingsPropertyValue(SettingsProperty property)
36 public object PropertyValue
42 _Value = Deserialize();
46 if (_Value != null && !Property.PropertyType.IsPrimitive && !(_Value is string) && !(_Value is DateTime))
48 _UsingDefaultValue = false;
49 _ChangedSinceLastSerialized = true;
59 _ChangedSinceLastSerialized = true;
61 _UsingDefaultValue = false;
65 public object SerializedValue
67 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
69 if (_ChangedSinceLastSerialized) {
70 _ChangedSinceLastSerialized = false;
71 _SerializedValue = SerializePropertyValue();
73 return _SerializedValue;
75 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
77 _UsingDefaultValue = false;
78 _SerializedValue = value;
82 public bool Deserialized
84 get { return _Deserialized; }
85 set { _Deserialized = value; }
88 [ResourceExposure(ResourceScope.None)]
89 [ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
90 private bool IsHostedInAspnet() {
91 // See System.Web.Hosting.ApplicationManager::PopulateDomainBindings
92 return AppDomain.CurrentDomain.GetData(".appDomain") != null;
95 private object Deserialize()
98 //////////////////////////////////////////////
99 /// Step 1: Try creating from Serailized value
100 if (SerializedValue != null)
103 if (SerializedValue is string) {
104 val = GetObjectFromString(Property.PropertyType, Property.SerializeAs, (string)SerializedValue);
106 MemoryStream ms = new System.IO.MemoryStream((byte[])SerializedValue);
108 val = (new BinaryFormatter()).Deserialize(ms);
114 catch (Exception exception) {
116 if (IsHostedInAspnet()) {
117 object[] args = new object[] { Property, this, exception};
119 const string webBaseEventTypeName = "System.Web.Management.WebBaseEvent, " + AssemblyRef.SystemWeb;
121 Type type = Type.GetType(webBaseEventTypeName, true);
123 type.InvokeMember("RaisePropertyDeserializationWebErrorEvent",
124 BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.InvokeMethod,
125 null, null, args, CultureInfo.InvariantCulture);
132 if (val != null && !Property.PropertyType.IsAssignableFrom(val.GetType())) // is it the correct type
136 //////////////////////////////////////////////
137 /// Step 2: Try creating from default value
140 _UsingDefaultValue = true;
141 if (Property.DefaultValue == null || Property.DefaultValue.ToString() == "[null]") {
142 if (Property.PropertyType.IsValueType)
143 return SecurityUtils.SecureCreateInstance(Property.PropertyType);
147 if (!(Property.DefaultValue is string)) {
148 val = Property.DefaultValue;
151 val = GetObjectFromString(Property.PropertyType, Property.SerializeAs, (string)Property.DefaultValue);
152 } catch(Exception e) {
153 throw new ArgumentException(SR.GetString(SR.Could_not_create_from_default_value, Property.Name, e.Message));
156 if (val != null && !Property.PropertyType.IsAssignableFrom(val.GetType())) // is it the correct type
157 throw new ArgumentException(SR.GetString(SR.Could_not_create_from_default_value_2, Property.Name));
160 //////////////////////////////////////////////
161 /// Step 3: Create a new one by calling the parameterless constructor
164 if (Property.PropertyType == typeof(string)) {
168 val = SecurityUtils.SecureCreateInstance(Property.PropertyType);
176 private static object GetObjectFromString(Type type, SettingsSerializeAs serializeAs, string attValue)
178 // Deal with string types
179 if (type == typeof(string) && (attValue == null || attValue.Length < 1 || serializeAs == SettingsSerializeAs.String))
182 // Return null if there is nothing to convert
183 if (attValue == null || attValue.Length < 1)
186 // Convert based on the serialized type
189 case SettingsSerializeAs.Binary:
190 byte[] buf = Convert.FromBase64String(attValue);
191 MemoryStream ms = null;
193 ms = new System.IO.MemoryStream(buf);
194 return (new BinaryFormatter()).Deserialize(ms);
200 case SettingsSerializeAs.Xml:
201 StringReader sr = new StringReader(attValue);
202 XmlSerializer xs = new XmlSerializer(type);
203 return xs.Deserialize(sr);
205 case SettingsSerializeAs.String:
206 TypeConverter converter = TypeDescriptor.GetConverter(type);
207 if (converter != null && converter.CanConvertTo(typeof(String)) && converter.CanConvertFrom(typeof(String)))
208 return converter.ConvertFromInvariantString(attValue);
209 throw new ArgumentException(SR.GetString(SR.Unable_to_convert_type_from_string, type.ToString()), "type");
216 private object SerializePropertyValue()
221 if (Property.SerializeAs != SettingsSerializeAs.Binary)
222 return ConvertObjectToString(_Value, Property.PropertyType, Property.SerializeAs, Property.ThrowOnErrorSerializing);
224 MemoryStream ms = new System.IO.MemoryStream();
226 BinaryFormatter bf = new BinaryFormatter();
227 bf.Serialize(ms, _Value);
235 private static string ConvertObjectToString(object propValue, Type type, SettingsSerializeAs serializeAs, bool throwOnError)
237 if (serializeAs == SettingsSerializeAs.ProviderSpecific) {
238 if (type == typeof(string) || type.IsPrimitive)
239 serializeAs = SettingsSerializeAs.String;
241 serializeAs = SettingsSerializeAs.Xml;
245 switch (serializeAs) {
246 case SettingsSerializeAs.String:
247 TypeConverter converter = TypeDescriptor.GetConverter(type);
248 if (converter != null && converter.CanConvertTo(typeof(String)) && converter.CanConvertFrom(typeof(String)))
249 return converter.ConvertToInvariantString(propValue);
250 throw new ArgumentException(SR.GetString(SR.Unable_to_convert_type_to_string, type.ToString()), "type");
251 case SettingsSerializeAs.Binary :
252 MemoryStream ms = new System.IO.MemoryStream();
254 BinaryFormatter bf = new BinaryFormatter();
255 bf.Serialize(ms, propValue);
256 byte[] buffer = ms.ToArray();
257 return Convert.ToBase64String(buffer);
262 case SettingsSerializeAs.Xml :
263 XmlSerializer xs = new XmlSerializer(type);
264 StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
266 xs.Serialize(sw, propValue);
267 return sw.ToString();
269 } catch (Exception) {
276 private object _Value = null;
277 private object _SerializedValue = null;
278 private bool _Deserialized = false;
279 private bool _IsDirty = false;
280 private SettingsProperty _Property = null;
281 private bool _ChangedSinceLastSerialized = false;
282 private bool _UsingDefaultValue = true;