背景:
阅读新闻

MemberShip中对用户资料的序列化

[日期:2004-12-14] 来源:宝玉的blog  作者:宝玉 [字体: ]

前面在《Asp.Net Forums中对.Net中序列化和反序列化的应用》一文中讲了,对于一些扩展属性,可以将字符串集合序列化为二进制,也可以从二进制反序列化为字符串集合。其实我一直有个疑问,对于asp.net中可以很容易实现,但是在asp中该如何?

CSDNN3中都采用了asp.net2.0的新特性MemberShip,今天研究了一下CSBeta2,特地研究了一下MemberShip中对于用户资料的序列化保存。发现在aspnet_Profile表中有三个特殊字段PropertyNames、PropertyValuesString和PropertyValuesBinary,其中的PropertyValuesBinary十之八九就是保存序列化为二进制后的内容。对于PropertyNames、PropertyValuesString这两个字段倒是不知道,打开查看,发现其中一条记录这两个字段的内容分别为下面两行的内容:

publicEmail:S:0:0:yahooIM:S:0:0:timezone:S:0:1:birthdate:B:0:-1:gender:S:1:6:location:S:7:0:fontsize:S:7:1:signature:S:8:0:dateFormat:S:8:10:webLog:S:18:7:enablePostPreviewPopup:B:0:-1:language:S:25:5:interests:S:30:0:occupation:S:30:0:webAddress:S:30:7:icqIM:S:37:0:aolIM:S:37:0:signatureFormatted:S:37:0:msnIM:S:37:0:


8NotSet0MM-dd-yyyyhttp://zh-CNhttp://

借助Reflector分析了一下源码,终于明白了,原来在PropertyNames字段中,由“:”分割为若干个数组,其中每个属性占数组的4项(如publicEmail:S:0:0:为一个属性的整体):
第1项为属性名称
第2项有两种可能值,B表示该属性值为null,S表示不为null
第3项表示在PropertyValuesString字段中字符串的起始位置
第4项表示长度
那么publicEmail:S:0:0:就表示为空值,timezone:S:0:1:表示“8NotSet0MM-dd-yyyyhttp://zh-CNhttp://“中从0开始取1个字符长度为“8”,birthdate:B:0:-1:就表示为null,dateFormat:S:8:10:就表示取“8NotSet0MM-dd-yyyyhttp://zh-CNhttp://”中第8位开始取10个字符为“MM-dd-yyyy”……

通过这种序列化为字符串的方式,即使是一些弱语言,如vbscript,jscript都可以实现序列化和反序列化了,那么在asp中也就可以共享asp.net的MemberShip了。

贴两段核心代码参考一下:

internal static void PrepareDataForSaving(ref string allNames, ref string allValues, ref byte[] buf, bool binarySupported, SettingsPropertyValueCollection properties, bool userIsAuthenticated) 

      StringBuilder builder1 = new StringBuilder(); 
      StringBuilder builder2 = new StringBuilder(); 
      MemoryStream stream1 = binarySupported ? new MemoryStream() : null; 
      try 
      { 
            bool flag1 = false; 
            foreach (SettingsPropertyValue value1 in properties) 
            { 
                  if (!value1.IsDirty) 
                  { 
                        continue; 
                  } 
                  if (userIsAuthenticated || ((bool) value1.Property.Attributes["AllowAnonymous"])) 
                  { 
                        flag1 = true; 
                        break; 
                  } 
            } 
            if (!flag1) 
            { 
                  return; 
            } 
            foreach (SettingsPropertyValue value2 in properties) 
            { 
                  if (!userIsAuthenticated && !((bool) value2.Property.Attributes["AllowAnonymous"])) 
                  { 
                        continue; 
                  } 
                  if (value2.IsDirty || !value2.UsingDefaultValue) 
                  { 
                        int num1 = 0; 
                        int num2 = 0; 
                        string text1 = null; 
                        if (value2.Deserialized && (value2.PropertyValue == null)) 
                        { 
                              num1 = -1; 
                        } 
                        else 
                        { 
                              object obj1 = value2.SerializedValue; 
                              if (obj1 == null) 
                              { 
                                    num1 = -1; 
                              } 
                              else 
                              { 
                                    if (!(obj1 is string) && !binarySupported) 
                                    { 
                                          obj1 = Convert.ToBase64String((byte[]) obj1); 
                                    } 
                                    if (obj1 is string) 
                                    { 
                                          text1 = (string) obj1; 
                                          num1 = text1.Length; 
                                          num2 = builder2.Length; 
                                    } 
                                    else 
                                    { 
                                          byte[] buffer1 = (byte[]) obj1; 
                                          num2 = (int) stream1.Position; 
                                          stream1.Write(buffer1, 0, buffer1.Length); 
                                          stream1.Position = num2 + buffer1.Length; 
                                          num1 = buffer1.Length; 
                                    } 
                              } 
                        } 
                        string[] textArray1 = new string[8] { value2.Name, ":", (text1 != null) ? "S" : "B", ":", num2.ToString(CultureInfo.InvariantCulture), ":", num1.ToString(CultureInfo.InvariantCulture), ":" } ; 
                        builder1.Append(string.Concat(textArray1)); 
                        if (text1 != null) 
                        { 
                              builder2.Append(text1); 
                        } 
                  } 
            } 
            if (binarySupported) 
            { 
                  buf = stream1.ToArray(); 
            } 
      } 
      catch 
      { 
            throw; 
      } 
      finally 
      { 
            if (stream1 != null) 
            { 
                  stream1.Close(); 
            } 
      } 
      allNames = builder1.ToString(); 
      allValues = builder2.ToString(); 

internal static void ParseDataFromDB(string[] names, string values, byte[] buf, SettingsPropertyValueCollection properties) 

      for (int num1 = 0; num1 < (names.Length / 4); num1++) 
      { 
            string text1 = names[num1 * 4]; 
            SettingsPropertyValue value1 = properties[text1]; 
            if (value1 != null) 
            { 
                  int num2 = int.Parse(names[(num1 * 4) + 2], CultureInfo.InvariantCulture); 
                  int num3 = int.Parse(names[(num1 * 4) + 3], CultureInfo.InvariantCulture); 
                  if (num3 == -1) 
                  { 
                        if (!value1.Property.PropertyType.IsValueType) 
                        { 
                              value1.PropertyValue = null; 
                              value1.IsDirty = false; 
                              value1.Deserialized = true; 
                        } 
                  } 
                  else 
                  { 
                        if (((names[(num1 * 4) + 1] == "S") && (num2 >= 0)) && ((num3 > 0) && (values.Length >= (num2 + num3)))) 
                        { 
                              value1.SerializedValue = values.Substring(num2, num3); 
                        } 
                        if (((names[(num1 * 4) + 1] == "B") && (num2 >= 0)) && ((num3 > 0) && (buf.Length >= (num2 + num3)))) 
                        { 
                              byte[] buffer1 = new byte[num3]; 
                              Buffer.BlockCopy(buf, num2, buffer1, 0, num3); 
                              value1.SerializedValue = buffer1; 
                        } 
                  } 
            } 
      } 

 

收藏 推荐 打印 | 录入:木鸟 | 阅读:
相关新闻       序列化 
本文评论   [发表评论]   全部评论 (0)
热门评论