namespace Wingtip.Providers { public class FileBasedPersonalizationProvider : PersonalizationProvider { public override string ApplicationName { get { ... } set { ... } } public override void Initialize( string name, NameValueCollection configSettings) { ... } public override int GetCountOfState(PersonalizationScope scope, PersonalizationStateQuery query) { ... } public override int ResetUserState(string path, DateTime userInactiveSinceDate) { ... } protected override void LoadPersonalizationBlobs( WebPartManager webPartManager, string path, string userName, ref byte[] sharedDataBlob, ref byte[] userDataBlob) { ... } protected override void ResetPersonalizationBlob( WebPartManager webPartManager, string path, string userName) { ... } public override int ResetState(PersonalizationScope scope, string[] paths, string[] usernames) { ... } protected override void SavePersonalizationBlob( WebPartManager webPartManager, string path, string userName, byte[] dataBlob) { ... } public override PersonalizationStateInfoCollection FindState( PersonalizationScope scope, PersonalizationStateQuery query, int pageIndex, int pageSize, out int totalRecords) { ... } } }
protected override void LoadPersonalizationBlobs( WebPartManager webPartManager, string path, string userName, ref byte[] sharedDataBlob, ref byte[] userDataBlob) { string allUsersFileName = HttpContext.Current.Server.MapPath( ConstructAllUsersDataFileName(path)); string userFileName = HttpContext.Current.Server.MapPath( ConstructUserDataFileName(userName, path)); allUsersFileName = string.Intern(allUsersFileName); userFileName = string.Intern(userFileName); try { // Read in shared user data first. // Lock on the file name in case two clients try accessing // the same file concurrently - note we lock on the Interned // file name string, which will always return the same object // for identical strings if (Monitor.TryEnter(allUsersFileName, 5000) && File.Exists(allUsersFileName)) sharedDataBlob = File.ReadAllBytes(allUsersFileName); else throw new ApplicationException("Monitor timed out"); // Next read in user specific data (if there is any) if (Monitor.TryEnter(userFileName, 5000) && File.Exists(userFileName)) userDataBlob = File.ReadAllBytes(userFileName); else throw new ApplicationException("Monitor timed out"); } finally { Monitor.Exit(allUsersFileName); Monitor.Exit(userFileName); } } protected override void SavePersonalizationBlob( WebPartManager webPartManager, string path, string userName, byte[] dataBlob) { string fileName = HttpContext.Current.Server.MapPath( string.IsNullOrEmpty(userName) ? ConstructAllUsersDataFileName(path) : ConstructUserDataFileName(userName, path)); fileName = string.Intern(fileName); try { // lock on the file name in case two clients try accessing // the same file concurrently if (Monitor.TryEnter(fileName, 5000)) { File.WriteAllBytes(HttpContext.Current.Server.MapPath( fileName), dataBlob); } else throw new ApplicationException("Monitor timed out"); } finally { Monitor.Exit(fileName); } } // Helper function for creating a unique file name for all users // based on a path private string ConstructAllUsersDataFileName(string path) { string fileName = path.Replace('/', '_').Replace('~', '_').Replace('.', '_'); return "~/App_Data/allusers" + fileName + ".bin"; } // Helper function for creating a unique file name for a particular // user based on a path private string ConstructUserDataFileName(string user, string path) { string fileName = path.Replace('/', '_').Replace('~', '_').Replace('.', '_'); return "~/App_Data/" + user + fileName + ".bin"; }
<webParts> <personalization defaultProvider="FileBasedPersonalizationProvider"> <providers> <add name="FileBasedPersonalizationProvider" type="Wingtip.Providers.FileBasedPersonalizationProvider" /> </providers> </personalization> </webParts>