1 //------------------------------------------------------------------------------
2 // <copyright file="ProfileModule.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
10 * Copyright (c) 1999 Microsoft Corporation
13 namespace System.Web.Profile {
16 using System.Web.Compilation;
17 using System.Web.Configuration;
18 using System.Web.Caching;
19 using System.Collections;
20 using System.Web.Util;
21 using System.Security.Principal;
22 using System.Security.Permissions;
23 using System.Reflection;
24 using System.Web.Security;
25 using System.Globalization;
26 using System.Runtime.Serialization;
27 using System.Collections.Specialized;
28 using System.Runtime.Serialization.Formatters.Binary;
30 using System.Xml.Serialization;
31 using System.ComponentModel;
32 using System.Configuration;
34 using System.Web.DataAccess;
35 #endif // !FEATURE_PAL
38 /// <para>[To be supplied.]</para>
40 public sealed class ProfileModule : IHttpModule
42 private static object s_Lock = new object();
43 private ProfileEventHandler _eventHandler = null;
45 private ProfileMigrateEventHandler _MigrateEventHandler;
46 private ProfileAutoSaveEventHandler _AutoSaveEventHandler;
50 /// Initializes a new instance of the <see cref='System.Web.Security.ProfileModule'/>
54 [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
55 public ProfileModule()
60 /// This is a Global.asax event which must be
61 /// named FormsAuthorize_OnAuthorize event. It's used by advanced users to
62 /// customize cookie authentication.
64 public event ProfileEventHandler Personalize
66 add { _eventHandler += value; }
67 remove { _eventHandler -= value; }
70 public event ProfileMigrateEventHandler MigrateAnonymous
72 add { _MigrateEventHandler += value; }
73 remove { _MigrateEventHandler -= value; }
76 public event ProfileAutoSaveEventHandler ProfileAutoSaving {
77 add { _AutoSaveEventHandler += value; }
78 remove { _AutoSaveEventHandler -= value; }
82 /// <para>[To be supplied.]</para>
89 /// <para>[To be supplied.]</para>
91 public void Init(HttpApplication app)
93 if (ProfileManager.Enabled) {
94 app.AcquireRequestState += new EventHandler(this.OnEnter);
95 if (ProfileManager.AutomaticSaveEnabled) {
96 app.EndRequest += new EventHandler(this.OnLeave);
101 private void OnPersonalize(ProfileEventArgs e)
103 if (_eventHandler != null)
104 _eventHandler(this, e);
106 if (e.Profile != null)
108 e.Context._Profile = e.Profile;
112 e.Context._ProfileDelayLoad = true;
115 ////////////////////////////////////////////////////////////
116 ////////////////////////////////////////////////////////////
117 ////////////////////////////////////////////////////////////
120 /// <para>[To be supplied.]</para>
122 private void OnEnter(Object source, EventArgs eventArgs)
124 HttpContext context = ((HttpApplication)source).Context;
125 OnPersonalize(new ProfileEventArgs(context));
126 if (context.Request.IsAuthenticated && !string.IsNullOrEmpty(context.Request.AnonymousID) && _MigrateEventHandler != null)
128 ProfileMigrateEventArgs e = new ProfileMigrateEventArgs(context, context.Request.AnonymousID);
129 _MigrateEventHandler(this, e);
133 private void OnLeave(Object source, EventArgs eventArgs)
135 HttpApplication app = (HttpApplication)source;
136 HttpContext context = app.Context;
138 if (context._Profile == null || (object)context._Profile == (object)ProfileBase.SingletonInstance)
141 if (_AutoSaveEventHandler != null) {
142 ProfileAutoSaveEventArgs args = new ProfileAutoSaveEventArgs(context);
143 _AutoSaveEventHandler(this, args);
144 if (!args.ContinueWithProfileAutoSave)
148 context.Profile.Save();
151 ////////////////////////////////////////////////////////////
152 ////////////////////////////////////////////////////////////
153 [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)]
154 internal static void ParseDataFromDB(string[] names, string values, byte[] buf, SettingsPropertyValueCollection properties)
156 if (names == null || values == null || buf == null || properties == null)
159 for (int iter = 0; iter < names.Length / 4; iter++) {
160 string name = names[iter * 4];
161 SettingsPropertyValue pp = properties[name];
163 if (pp == null) // property not found
166 int startPos = Int32.Parse(names[iter * 4 + 2], CultureInfo.InvariantCulture);
167 int length = Int32.Parse(names[iter * 4 + 3], CultureInfo.InvariantCulture);
169 if (length == -1 && !pp.Property.PropertyType.IsValueType) // Null Value
171 pp.PropertyValue = null;
173 pp.Deserialized = true;
175 if (names[iter * 4 + 1] == "S" && startPos >= 0 && length > 0 && values.Length >= startPos + length) {
176 pp.SerializedValue = values.Substring(startPos, length);
179 if (names[iter * 4 + 1] == "B" && startPos >= 0 && length > 0 && buf.Length >= startPos + length) {
180 byte[] buf2 = new byte[length];
182 Buffer.BlockCopy(buf, startPos, buf2, 0, length);
183 pp.SerializedValue = buf2;
186 } catch { // Eat exceptions
190 ////////////////////////////////////////////////////////////
191 ////////////////////////////////////////////////////////////
192 ////////////////////////////////////////////////////////////
193 [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)]
194 internal static void PrepareDataForSaving(ref string allNames, ref string allValues, ref byte[] buf, bool binarySupported, SettingsPropertyValueCollection properties, bool userIsAuthenticated)
196 StringBuilder names = new StringBuilder();
197 StringBuilder values = new StringBuilder();
199 MemoryStream ms = (binarySupported ? new System.IO.MemoryStream() : null);
202 bool anyItemsToSave = false;
204 foreach (SettingsPropertyValue pp in properties) {
206 if (!userIsAuthenticated) {
207 bool allowAnonymous = (bool)pp.Property.Attributes["AllowAnonymous"];
211 anyItemsToSave = true;
219 foreach (SettingsPropertyValue pp in properties) {
220 if (!userIsAuthenticated) {
221 bool allowAnonymous = (bool)pp.Property.Attributes["AllowAnonymous"];
226 if (!pp.IsDirty && pp.UsingDefaultValue) // Not fetched from DB and not written to
229 int len = 0, startPos = 0;
230 string propValue = null;
232 if (pp.Deserialized && pp.PropertyValue == null) // is value null?
236 object sVal = pp.SerializedValue;
241 if (!(sVal is string) && !binarySupported) {
242 sVal = Convert.ToBase64String((byte[])sVal);
245 if (sVal is string) {
246 propValue = (string)sVal;
247 len = propValue.Length;
248 startPos = values.Length;
250 byte[] b2 = (byte[])sVal;
251 startPos = (int)ms.Position;
252 ms.Write(b2, 0, b2.Length);
253 ms.Position = startPos + b2.Length;
259 names.Append(pp.Name + ":" + ((propValue != null) ? "S" : "B") +
260 ":" + startPos.ToString(CultureInfo.InvariantCulture) + ":" + len.ToString(CultureInfo.InvariantCulture) + ":");
261 if (propValue != null)
262 values.Append(propValue);
265 if (binarySupported) {
275 allNames = names.ToString();
276 allValues = values.ToString();
280 public delegate void ProfileMigrateEventHandler(Object sender, ProfileMigrateEventArgs e);
282 public sealed class ProfileMigrateEventArgs : EventArgs {
283 private HttpContext _Context;
284 private string _AnonymousId;
286 public HttpContext Context { get { return _Context;}}
288 public string AnonymousID { get { return _AnonymousId;}}
290 public ProfileMigrateEventArgs(HttpContext context, string anonymousId) {
292 _AnonymousId = anonymousId;
296 public delegate void ProfileAutoSaveEventHandler(Object sender, ProfileAutoSaveEventArgs e);
298 public sealed class ProfileAutoSaveEventArgs : EventArgs
300 private HttpContext _Context;
301 private bool _ContinueSave = true;
303 public HttpContext Context { get { return _Context; } }
304 public bool ContinueWithProfileAutoSave { get { return _ContinueSave; } set { _ContinueSave = value; }}
306 public ProfileAutoSaveEventArgs(HttpContext context) {