宝玉的blog

专注于web开发技术
随笔 - 78, 评论 - 1563, 引用 - 157

导航

关于


目前致力于ChinaCommunityServer的开发。

msn: junminliu(at)msn.com

每月存档

最新留言

  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:37
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:31
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:30
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:29
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:25
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:25
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:25
  • re:Openlab V2.0 Beta
    <p>宝玉你好: &nbsp; &nbsp; &nbsp; 我是个.net新手,最近看了openlab(openlab_V2.0_Beta)的源码。 ...
    by isforge(注册) on 2009/6/28 10:10:25
  • re:Silverlight中,防止ComboBox抢焦点
    在家”用网路”赚全世界的钱! 这是真正实现跨国事业最好的机制。藉由网路无远弗届的力量, 让全球超过180个国家变成一个单一市场,在你加入的那一刻, 网路能到达的地方,就是你收入能到达的地方。 ...
    by jackielongteng(注册) on 2009/6/14 13:19:48
  • re:Silverlight中,防止ComboBox抢焦点
    <p>我是初学者,您已经写了一个 组件上传的功能 。。我在2008下测试通过,,,但是弄2005测试的时候 发现 progress.aspx.cs页面的</p> <p&...
    by jxh12345j(注册) on 2009/4/7 8:55:12
  • ufnnutdh - Google Search
    ufnnutdh - Google Search
    by (匿名) on 2008/10/27 17:44:45
  • veysaync - Google Search
    veysaync - Google Search
    by (匿名) on 2008/10/5 5:20:49
  • mzgmhgio - Google Search
    mzgmhgio - Google Search
    by (匿名) on 2008/9/22 23:34:49
  • rhmhnyma - Google Search
    rhmhnyma - Google Search
    by (匿名) on 2008/9/22 7:48:44
  • re: 发布一个爱心小软件——网页抓图
    Maxthon应该有这个功能
    by passos(匿名) on 2008/7/21 20:05:23

广告

 

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

                  }

            }

      }

}

 

打印 | 张贴于 2004-12-14 02:10:00

留言反馈

#回复: MemberShip中对用户资料的序列化 编辑
上述代码在实际应用中会出现问题,主要是ado.net 中 eval得换成val,当PropertyNames为''或null时会出现类型错误的问题,修改后代码如下

"IIf(PropertyNames='' or PropertyNames is Null,'',Mid(PropertyValues,Val(Mid(Mid(PropertyNames,InStr(1,PropertyNames,'" + property.Name + "')+Len('" + property.Name + "')+3),1,InStr(1,Mid(PropertyNames,InStr(1,PropertyNames,'" + property.Name + "')+Len('" + property.Name + "')+3),':')-1))+1,4)) = '" + property.Value + "'"
2007-11-30 13:44:00 | [匿名用户:Robot.Crazy]
#回复: MemberShip中对用户资料的序列化 编辑
在《Asp.Net Forums中对.Net中序列化和反序列化的应用》一文中提到无法进行有效查询。解决方案如下:
构造查询字符串,通过提取PropertyNames中的StartIndex,提取出PropertyValueString中的值,然后同给定的值进行比较
我使用的是Accss,具体如下所示:

SELECT *
FROM UsersDataAdapter where Mid(PropertyValues,eval(Mid(Mid(PropertyNames,InStr(1,PropertyNames,"IsPublic")+Len("IsPublic")+3),1,InStr(1,Mid(PropertyNames,InStr(1,PropertyNames,"IsPublic")+Len("IsPublic")+3),":")-1))+1,4) = "True"

将IsPublic替换成属性名称,将True替换成属性值,搞定。
2007-11-29 20:53:00 | [匿名用户:Robot.Crazy]
#回复: MemberShip中对用户资料的序列化 编辑
收益匪浅.
收藏
2006-12-25 16:17:00 | [匿名用户:虫子]
#回复: MemberShip中对用户资料的序列化 编辑
收益匪浅.
2006-12-25 16:10:00 | [匿名用户:虫子]
#re: MemberShip中对用户资料的序列化 编辑
to jhyc:
这个我不清楚,如果你怀疑自己系统有问题,可以换个机器看看:)
2005-02-24 11:30:00 | [匿名用户:宝玉]
#re: MemberShip中对用户资料的序列化 编辑
宝玉大哥,我下了份ActiproSoftware.CodeHighlighter ,可打开后就发现叶面上的CodeHighlighter不能显示阿,是不是我的系统有问题阿?
2005-02-24 11:20:00 | [匿名用户:jhyc]
#MemberShip中对用户资料的序列化 编辑
Ping Back来自:blog.csdn.net
2005-01-12 10:07:00 | [匿名用户:缎雨]
#re: MemberShip中对用户资料的序列化 编辑
非要我说明白,这里就是看M$的小道消息:)
技术文章当然是没错,我是说不合适这里的气氛而已。
当然blog嘛,愿在哪儿写就在哪儿写了,自己的事。
2004-12-21 22:27:00 | [匿名用户:birdshome]
#re: MemberShip中对用户资料的序列化 编辑
我想看官方消息可以去ms网站去看吧,博客堂本身定位也不是只发布微软准官方消息的,要不然这里就只有MS的人了。

我想不管怎么样发技术文章应该没有错,至少这些技术对一些人还是能或多或少有些帮助。
2004-12-21 12:47:00 | [匿名用户:宝玉]
#re: MemberShip中对用户资料的序列化 编辑
还是回博客园吧,这些文章并不太适合这里的气氛,感觉怪怪的。
来这儿主要都是看些M$的准"官方"消息。
2004-12-21 11:29:00 | [匿名用户:birdshome]
#re: MemberShip中对用户资料的序列化 编辑
宝玉兄,能否告诉我你的代码怎么贴上去的,居然还有折叠功能呀?多谢
2004-12-18 13:00:00 | [匿名用户:Alex]
#re: MemberShip中对用户资料的序列化 编辑
宝玉兄,你好,很高兴看到你这篇随笔,我昨天在作dnn模块迁移的时候也碰到类似的疑问。dnn3中有一个用户表users,只保存了username信息,而password、email是保存在aspnet_MemberShip中的,但是我现在的疑问是:users的userid是int,而aspnet_MemberShip却没有对应的字段,我不明白users和aspnet_MemberShip两个表是如何进行相关联的。谢谢!
2004-12-14 09:21:00 | [匿名用户:boy119]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.1.8