2 // System.Web.UI.WebControls.ProfileBase.cs
5 // Chris Toshok (toshok@ximian.com)
6 // Vladimir Krasnov (vladimirk@mainsoft.com)
8 // (C) 2005 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Configuration;
33 using System.Configuration.Provider;
34 using System.Web.Security;
35 using System.Web.Configuration;
36 using System.Reflection;
38 namespace System.Web.Profile
40 public class ProfileBase : SettingsBase
42 bool _propertiyValuesLoaded = false;
44 DateTime _lastActivityDate = DateTime.MinValue;
45 DateTime _lastUpdatedDate = DateTime.MinValue;
46 SettingsContext _settingsContext = null;
47 SettingsPropertyValueCollection _propertiyValues = null;
48 const string Profiles_SettingsPropertyCollection = "Profiles.SettingsPropertyCollection";
51 static SettingsPropertyCollection _properties
55 object o = AppDomain.CurrentDomain.GetData (Profiles_SettingsPropertyCollection);
56 return (SettingsPropertyCollection) o;
60 AppDomain.CurrentDomain.SetData (Profiles_SettingsPropertyCollection, value);
64 static SettingsPropertyCollection _properties = null;
67 static void InitProperties ()
69 SettingsPropertyCollection properties = new SettingsPropertyCollection ();
71 ProfileSection config = (ProfileSection) WebConfigurationManager.GetSection ("system.web/profile");
72 RootProfilePropertySettingsCollection ps = config.PropertySettings;
74 for (int i = 0; i < ps.GroupSettings.Count; i++) {
75 ProfileGroupSettings pgs = ps.GroupSettings [i];
76 ProfilePropertySettingsCollection ppsc = pgs.PropertySettings;
78 for (int s = 0; s < ppsc.Count; s++) {
79 SettingsProperty settingsProperty = CreateSettingsPropery (pgs, ppsc [s]);
80 ValidateProperty (settingsProperty, ppsc [s].ElementInformation);
81 properties.Add (settingsProperty);
85 for (int s = 0; s < ps.Count; s++) {
86 SettingsProperty settingsProperty = CreateSettingsPropery (null, ps [s]);
87 ValidateProperty (settingsProperty, ps [s].ElementInformation);
88 properties.Add (settingsProperty);
91 if (config.Inherits.Length > 0) {
92 Type profileType = ProfileParser.GetProfileCommonType (HttpContext.Current);
93 if (profileType != null) {
94 Type properiesType = profileType.BaseType;
96 PropertyInfo [] pi = properiesType.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
98 for (int i = 0; i < pi.Length; i++)
99 properties.Add (CreateSettingsPropery (pi [i]));
101 if (properiesType.BaseType == null ||
102 properiesType.BaseType == typeof (ProfileBase))
105 properiesType = properiesType.BaseType;
110 properties.SetReadOnly ();
111 lock (Profiles_SettingsPropertyCollection) {
112 if (_properties == null)
113 _properties = properties;
117 public ProfileBase ()
121 public static ProfileBase Create (string username)
123 return Create (username, true);
126 public static ProfileBase Create (string username, bool isAuthenticated)
128 ProfileBase profile = null;
129 Type profileType = ProfileParser.GetProfileCommonType (HttpContext.Current);
130 if (profileType != null)
131 profile = (ProfileBase) Activator.CreateInstance (profileType);
133 profile = (ProfileBase) new DefaultProfile ();
135 profile.Initialize (username, isAuthenticated);
139 public ProfileGroupBase GetProfileGroup (string groupName)
141 ProfileGroupBase group = null;
142 Type groupType = ProfileParser.GetProfileGroupType (HttpContext.Current, groupName);
143 if (groupType != null)
144 group = (ProfileGroupBase) Activator.CreateInstance (groupType);
146 throw new ProviderException ("Group '" + groupName + "' not found");
148 group.Init (this, groupName);
152 public object GetPropertyValue (string propertyName)
154 if (!_propertiyValuesLoaded)
155 InitPropertiesValues ();
157 _lastActivityDate = DateTime.UtcNow;
159 return ((SettingsPropertyValue) _propertiyValues [propertyName]).PropertyValue;
162 public void SetPropertyValue (string propertyName, object propertyValue)
164 if (!_propertiyValuesLoaded)
165 InitPropertiesValues ();
167 if (_propertiyValues [propertyName] == null)
168 throw new SettingsPropertyNotFoundException ("The settings property '" + propertyName + "' was not found.");
170 if (!(bool)((SettingsPropertyValue)
171 _propertiyValues [propertyName]).Property.Attributes["AllowAnonymous"] && IsAnonymous)
172 throw new ProviderException ("This property cannot be set for anonymous users.");
174 ((SettingsPropertyValue) _propertiyValues [propertyName]).PropertyValue = propertyValue;
176 _lastActivityDate = DateTime.UtcNow;
177 _lastUpdatedDate = _lastActivityDate;
180 public override object this [string propertyName]
184 return GetPropertyValue (propertyName);
188 SetPropertyValue (propertyName, value);
192 void InitPropertiesValues ()
194 if (!_propertiyValuesLoaded) {
195 _propertiyValues = ProfileManager.Provider.GetPropertyValues (_settingsContext, Properties);
196 _propertiyValuesLoaded = true;
200 static Type GetPropertyType (ProfileGroupSettings pgs, ProfilePropertySettings pps)
202 Type type = HttpApplication.LoadType (pps.Type);
206 Type profileType = null;
208 profileType = ProfileParser.GetProfileCommonType (HttpContext.Current);
210 profileType = ProfileParser.GetProfileGroupType (HttpContext.Current, pgs.Name);
212 if (profileType == null)
215 PropertyInfo pi = profileType.GetProperty (pps.Name);
217 return pi.PropertyType;
222 static void ValidateProperty (SettingsProperty settingsProperty, ElementInformation elementInfo)
224 string exceptionMessage = string.Empty;
225 if (!AnonymousIdentificationModule.Enabled &&
226 (bool) settingsProperty.Attributes ["AllowAnonymous"])
227 exceptionMessage = "Profile property '{0}' allows anonymous users to store data. " +
228 "This requires that the AnonymousIdentification feature be enabled.";
230 if (settingsProperty.PropertyType == null)
231 exceptionMessage = "The type specified for a profile property '{0}' could not be found.";
233 if (settingsProperty.SerializeAs == SettingsSerializeAs.Binary &&
234 !settingsProperty.PropertyType.IsSerializable)
235 exceptionMessage = "The type for the property '{0}' cannot be serialized " +
236 "using the binary serializer, since the type is not marked as serializable.";
238 if (exceptionMessage.Length > 0)
239 throw new ConfigurationErrorsException (string.Format (exceptionMessage, settingsProperty.Name),
240 elementInfo.Source, elementInfo.LineNumber);
243 static SettingsProperty CreateSettingsPropery (PropertyInfo property)
245 SettingsProperty sp = new SettingsProperty (property.Name);
247 Attribute [] attributes = (Attribute [])property.GetCustomAttributes (typeof (SettingsSerializeAsAttribute), false);
248 SettingsAttributeDictionary attDict = new SettingsAttributeDictionary();
249 sp.SerializeAs = SettingsSerializeAs.ProviderSpecific;
250 sp.PropertyType = property.PropertyType;
251 sp.IsReadOnly = false;
252 sp.ThrowOnErrorDeserializing = false;
253 sp.ThrowOnErrorSerializing = true;
255 for (int i = 0; i < attributes.Length; i++) {
256 if (attributes [i] is DefaultSettingValueAttribute)
257 sp.DefaultValue = ((DefaultSettingValueAttribute) attributes [i]).Value;
259 else if (attributes [i] is SettingsProviderAttribute) {
260 Type providerType = HttpApplication.LoadType (((SettingsProviderAttribute) attributes [i]).ProviderTypeName);
261 sp.Provider = (SettingsProvider) Activator.CreateInstance (providerType);
262 sp.Provider.Initialize (null, null);
265 else if (attributes [i] is SettingsSerializeAsAttribute)
266 sp.SerializeAs = ((SettingsSerializeAsAttribute) attributes [i]).SerializeAs;
269 attributes [i] is SettingsAllowAnonymousAttribute ||
270 attributes [i] is ApplicationScopedSettingAttribute ||
271 attributes [i] is UserScopedSettingAttribute ||
272 attributes [i] is SettingsDescriptionAttribute ||
273 attributes [i] is SettingAttribute)
274 attDict.Add (attributes [i].GetType (), attributes [i]);
277 if (sp.Provider == null)
278 sp.Provider = ProfileManager.Provider;
280 if (sp.Attributes ["AllowAnonymous"] == null)
281 sp.Attributes ["AllowAnonymous"] = false;
285 static SettingsProperty CreateSettingsPropery (ProfileGroupSettings pgs, ProfilePropertySettings pps)
287 string name = ((pgs == null) ? "" : pgs.Name + ".") + pps.Name;
288 SettingsProperty sp = new SettingsProperty (name);
290 sp.Attributes.Add ("AllowAnonymous", pps.AllowAnonymous);
291 sp.DefaultValue = pps.DefaultValue;
292 sp.IsReadOnly = pps.ReadOnly;
293 sp.Provider = ProfileManager.Provider;
294 sp.ThrowOnErrorDeserializing = false;
295 sp.ThrowOnErrorSerializing = true;
297 if (pps.Type.Length == 0 || pps.Type == "string")
298 sp.PropertyType = typeof (string);
300 sp.PropertyType = GetPropertyType (pgs, pps);
302 switch (pps.SerializeAs) {
303 case SerializationMode.Binary:
304 sp.SerializeAs = SettingsSerializeAs.Binary;
306 case SerializationMode.ProviderSpecific:
307 sp.SerializeAs = SettingsSerializeAs.ProviderSpecific;
309 case SerializationMode.String:
310 sp.SerializeAs = SettingsSerializeAs.String;
312 case SerializationMode.Xml:
313 sp.SerializeAs = SettingsSerializeAs.Xml;
321 public void Initialize (string username, bool isAuthenticated)
323 _settingsContext = new SettingsContext ();
324 _settingsContext.Add ("UserName", username);
325 _settingsContext.Add ("IsAuthenticated", isAuthenticated);
326 SettingsProviderCollection spc = new SettingsProviderCollection();
327 spc.Add (ProfileManager.Provider);
328 base.Initialize (Context, ProfileBase.Properties, spc);
331 public override void Save ()
334 ProfileManager.Provider.SetPropertyValues (_settingsContext, _propertiyValues);
338 public bool IsAnonymous {
340 return !(bool) _settingsContext ["IsAuthenticated"];
344 public bool IsDirty {
350 public DateTime LastActivityDate {
352 return _lastActivityDate;
356 public DateTime LastUpdatedDate {
358 return _lastUpdatedDate;
362 public new static SettingsPropertyCollection Properties {
364 if (_properties == null)
371 public string UserName {
373 return (string) _settingsContext ["UserName"];