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>