加载没有HTTP上下文的ProfileBase

时间:2013-02-08 20:03:30

标签: asp.net asp.net-membership

我正在转换在经典ASP.Net成员资格提供程序中序列化的用户配置文件数据,以便在SimpleMembership中使用。我无法弄清楚如何为系统中的每个用户获取ProfileBase对象。

如果特定的用户已登录,我可以执行以下操作:

MyModel myModel = 
    (MyModel)HttpContext.Current.Profile.GetPropertyValue("MyKey");

其中 MyKey 是指在web.config中建立的个人资料密钥,如下所示:

<add name="MyModel" type="MyNS.MyModel" serializeAs="Binary" />

但是,如果没有HTTP上下文的好处(我正在尝试为系统中的所有用户执行此操作,而不是登录用户),我无法弄清楚如何加载配置文件并最终实现系统中的每个用户都有MyModel

我试过了:

ProfileInfoCollection profiles = 
     ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);

foreach (var profile in profiles)
{
    var pi = (ProfileBase)profile;
    // OOPS!  Unfortunately GetAllProfiles returns 
    // ProfileInfo and not ProfileCommon or ProfileBase
}

MembershipUserCollection existingUsers = Membership.GetAllUsers();
foreach (MembershipUser mu in existingUsers)
{
    mu. // OOPS! No link to the profile from the user...
}

如何为系统中的每个配置文件检索ProfileCommonProfileBase实例,从而最终检索与每个用户相关联的MyModel

2 个答案:

答案 0 :(得分:0)

由于我找不到这个问题的答案,我选择直接从SQL中读取配置文件数据。

事实证明,格式很简单。在aspnet_Profile中:

  • PropertyNames使用格式NameOfProperty:TypeFlag:Offset:Length(对所有属性都重复)。
  • FlagType为“S”表示字符串,“B”表示二进制
  • 偏移量是相应数据字段中的偏移量
  • 长度是相应数据字段中的数据长度
  • PropertyValuesString保存所有没有分隔符的串联的字符串属性。
  • PropertyValuesBinary保存所有没有分隔符的连接的二进制属性。
  • BinaryFormatter用于序列化二进制(非字符串)属性

这是我编写的用于解析数据的一些代码:

private class Migrate_PropNames
{
    public string Name { get; set; }
    public bool IsString { get; set; }
    public int Offset { get; set; }
    public int Length { get; set; }
}
....

Dictionary<string, Migrate_PropNames> propInfo = ParsePropInfo(propertyNames);
// Example string property
string firstName = Migrate_GetString(propInfo["FirstName"], propertyValuesString);
// Example binary property
MyType myType = 
    Migrate_GetBinary<MyType>(propInfo["MyTypeKey"], propertyValuesBinary));


private T Migrate_GetBinary<T>(Migrate_PropNames propNames, byte[] propertyValuesBinary)
{
    byte[] data = new byte[propNames.Length];
    Array.Copy(propertyValuesBinary, propNames.Offset, data, 0, propNames.Length);

    var fmt = new BinaryFormatter();
    using (var ms = new MemoryStream(data))
    {
        T original = (T)fmt.Deserialize(ms);
        return original;
    }
}

private string Migrate_GetString(Migrate_PropNames propNames, string propertyNames)
{
    return propertyNames.Substring(propNames.Offset, propNames.Length);
}

private Dictionary<string, Migrate_PropNames> ParsePropInfo(string propertyNames)
{
    Dictionary<string, Migrate_PropNames> result = new Dictionary<string,Migrate_PropNames>();

    string[] parts = propertyNames.Split(new string[] { ":"}, StringSplitOptions.RemoveEmptyEntries);
    for (int i = 0; i < parts.Length; i += 4)
    {
        Migrate_PropNames pn = new Migrate_PropNames();
        pn.Name = parts[i];
        pn.IsString = (parts[i + 1] == "S");
        pn.Offset = int.Parse(parts[i + 2]);
        pn.Length = int.Parse(parts[i + 3]);

        result.Add(pn.Name, pn);
    }

    return result;
}

我希望这有助于某人。我很乐意接受一个正确显示如何使用API​​的不同答案。

答案 1 :(得分:0)

ProfileInfoMemberShipUser对象,您应该使用ProfileBase获得ProfileBase.Create(string username)个。{/ p>