现在的位置: 首页 > 综合 > 正文

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

2013年09月13日 ⁄ 综合 ⁄ 共 5589字 ⁄ 字号 评论关闭
 

前面在《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)

抱歉!评论已关闭.