如果你希望能够在 ViewState 中保存 Self-Tracking Entities 对象,那么,将会遇到不能序列化的问题。

问题的原因在于 ViewState 通过将对象序列化之后通过隐藏域保存在网页中,所以,希望通过 ViewState 进行状态管理的对象必须支持序列化。

但是 Self-Tracking Entities 中生成的类没有序列化的标签,所以,导致使用失败。

幸运的是,Self-Tracking Entities 是通过 T4 - Text Template Transformation Toolkit 来生成代码的。

关于 T4 - Text Template Transformation Toolkit  可以参考我的另外一篇文章。VS2010 中的代码生成器 T4 - Text Template Transformation Toolkit

默认的  Self-Tracking Entities  模板中没有包含我们需要的标记说明来支持序列化,好消息就是我们可以简单的编辑一下  Self-Tracking Entities  的  T4 模板就可以了。

我们需要这几步就可以:

1. 增加 [Serializable] 标签到实体,复杂类型和集合类

2. 为字典集合类增加必须的序列化构造器

3. 为实体和复杂类型的 OnDerserializedMethod  方法增加一些代码,当一个实体被反序列化的时候来注册变化的跟踪事件

但是在  Silverlight 中还没有二进制的序列化。所以,如果你做了上面第1 和第 2 步的修改,那么,在 Silverlight 中将不能通过编译。

Self-Tracking Entities  在你的项目中加入了两个模板,其中一个用来生成 ObjectContext ,另外一个用来生成实体,我们需要修改的内容就在第二个用来生成实体的模板中。

第一件事就是给所有的类增加 [Serializable] 标签 以支持序列化。

先找到 37 行,增加 [Serializable] 后,应该如下所示:

37 [Serializable]
38 <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#><#=entity.BaseType == null ? ": " : ", "#>IObjectWithChangeTracker, INotifyPropertyChanged
 

后面的修改依次如下。

1403: [Serializable]
1404: public class TrackableCollection<T> : ObservableCollection<T>
1405: {
1428: [Serializable]
1429: public class ObjectChangeTracker
1430: {
1650: [Serializable]
1651: public class ObjectsAddedToCollectionProperties : Dictionary<string, ObjectList>
1652  { }
1655: [Serializable]
1656: public class ObjectsRemovedFromCollectionProperties : Dictionary<string,
       ObjectList> { }
1660: [Serializable]
1661: public class OriginalValuesDictionary : Dictionary<string, Object> { }
1665: [Serializable]
1666: public class ExtendedPropertiesDictionary : Dictionary<string, Object> { }
1669: [Serializable]
1670: public class ObjectList : List<object> { }

序列化构造器

下一步,我们要确认所有从 Dictionary<> 派生的类都完全支持序列化。

由于 Dictionary<> 类通过实现接口  ISerializable 来实现了自定义的序列化,所以,所有派生自 Dictionary<> 的类必须有一个特制的用于反序列化的构造函数。

并不需要我们为构造函数增加什么代码,仅仅需要有构造函数来支持  Dictionary<>  的反序列化。这里有四个类需要做修改。

ObjectsAddedToCollectionProperties 类

 1651: public class ObjectsAddedToCollectionProperties : Dictionary<string, ObjectList>
 1652: {
 1653:     public ObjectsAddedToCollectionProperties() { }
 1654:
 1655:     protected ObjectsAddedToCollectionProperties(SerializationInfo info,
 1656:                                                  StreamingContext ctx) 
 1657:         : base(info, ctx)
 1658:     { }
 1659: }

ObjectsRemovedFromCollectionProperties 类

 1664: public class ObjectsRemovedFromCollectionProperties : Dictionary<string, ObjectList>
 1665: {
 1666:     public ObjectsRemovedFromCollectionProperties() { }
 1667:
 1668:     protected ObjectsRemovedFromCollectionProperties(SerializationInfo info, 
 1669:                                                      StreamingContext ctx) 
 1670:        : base(info, ctx)
 1671:    { }
 1672: }

OriginalValuesDictionary 类

 1677: public class OriginalValuesDictionary : Dictionary<string, Object>
 1678: {
 1679:     public OriginalValuesDictionary() { }
 1680:
 1681:     protected OriginalValuesDictionary(SerializationInfo info,
 1682:                                        StreamingContext ctx) 
 1683:         : base(info, ctx)
 1684:     { }
 1685: }

最后,ExtendedPropertiesDictionary 类

 1690: public class ExtendedPropertiesDictionary : Dictionary<string, Object>
 1691: {
 1692:     public ExtendedPropertiesDictionary() { }
 1693:
 1694:     protected ExtendedPropertiesDictionary(SerializationInfo info, 
 1695:                                            StreamingContext ctx) 
 1696:         : base(info, ctx)
 1697:     { }
 1698: }

事件的处理

由于在进行二进制序列化的时候不会序列化事件的处理,所以,在反序列化之后,我们可以通过 OnDeserialized  方法来执行一些我们自己的代码完成这个工作。

为了给实体增加这些工作,我们可以在模板中找到 OnDeserializedMethod  方法,然后增加三种重要的事件处理:

复杂类型事件处理

双向连接的集合属性的事件处理

级联删除的事件处理

将原来的 OnDeserializedMethod 方法直接用下面的替换掉

[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
    IsDeserializing = false;
    ChangeTracker.ChangeTrackingEnabled = true;
<#
// Hook up ComplexType property event handlers
foreach(EdmProperty edmProperty in entity.Properties
    .Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity))
{
#>
    if (<#=code.FieldName(edmProperty)#> != null)
    {
        ((INotifyComplexPropertyChanging)<#=code.FieldName(edmProperty)#>)
             .ComplexPropertyChanging -= Handle<#=edmProperty.Name#>Changing;
        ((INotifyComplexPropertyChanging)<#=code.FieldName(edmProperty)#>)
             .ComplexPropertyChanging += Handle<#=edmProperty.Name#>Changing;
    }
<#
}
// Hook up Collection property event handlers
foreach (NavigationProperty navProperty in entity.NavigationProperties
    .Where(np => np.DeclaringType == entity))
{
    if (navProperty.ToEndMember.RelationshipMultiplicity ==
                                          RelationshipMultiplicity.Many)
    {
#>
    if (<#=code.FieldName(navProperty)#> != null)
    {
        <#=code.FieldName(navProperty)#>.CollectionChanged -= Fixup<#=navProperty.Name#>;
        <#=code.FieldName(navProperty)#>.CollectionChanged += Fixup<#=navProperty.Name#>;
<#
        if (ef.IsCascadeDeletePrincipal(navProperty))
        {
#>
        // This is the principal end in an association that performs cascade deletes.
        // Add the cascade delete event handler for any entities that are 
        // already in the collection.
        foreach (var item in <#=code.FieldName(navProperty)#>)
        {
            ChangeTracker.ObjectStateChanging -= item.HandleCascadeDelete;
            ChangeTracker.ObjectStateChanging += item.HandleCascadeDelete;
        }
<#
        }
#>
    }
<#
    }
}
#>
}

完成上面的这些修改之后,你的 self-tracking entities 应该可以进行二进制序列化了,也就可以通过 ViewState 进行状态管理。

在 Jeff Derstadt 的文章 Using Binary Serialization and ViewState with Self-Tracking Entities 中,还给出了一个已经修改好的模版文件,这是链接地址:完成的模版

这篇文章来自:Jeff Derstadt 的文章,这是原文的链接:http://blogs.msdn.com/b/adonet/archive/2010/05/26/using-binary-serialization-and-viewstate-with-self-tracking-entities.aspx

转载于:https://www.cnblogs.com/haogj/archive/2010/06/12/1757449.html

通过 ViewState 保存 Self-Tracking Entities相关推荐

  1. ASP.Net ViewState的实现

    选择自 timmy3310 的 Blog ViewState是.Net中提出的状态保存的一种新途径(实际上也是老瓶装新酒):我们知道,传统的Web程序保存状态的方式有这样几种:   1.Applica ...

  2. 艾伟:控件之ViewState

    主题,控件的viewstate状态 一"七七八八" 有次,朋友开玩笑说,不知道什么时候,微软会取消viewstate,不再使用隐藏字段在服务器与客户端保存状态!虽然,可以使用客户端 ...

  3. ViewState与Session 的重要区别

    ViewState 指的是当前页面的视图状态(不同于控件的视图状态), ViewState 可以将任意支持序列化的对象保存到页面中, 它与 Session 的重要区别有两个: 第一.ViewState ...

  4. [转]用 ASP.NET 2.0 改进的 ViewState 加快网站速度

    本文讨论: • ViewState 如何工作 • ASP.NET 2.0 ViewState 的改进 • 使用控件状态维护功能 • 性能考虑 本文使用以下技术: ASP.NET.C# 代码下载: Vi ...

  5. .Net ViewState的实现(转载)

    ViewState是.Net中提出的状态保存的一种新途径(实际上也是老瓶装新酒):我们知道,传统的Web程序保存状态的方式有这样几种:   1.Application 这是Web应用程序生命期中的全局 ...

  6. [木野狐]ViewState 剖析(翻译兼笔记)

    [木野狐]ViewState 剖析(翻译兼笔记) 原文链接:ViewState: All You Wanted to Know 作者:Paul Wilson翻译:木野狐 ViewState 不是什么? ...

  7. viewstate java_ASP.NET之ViewState

    什么是ViewState? 在asp时代, 大家都知道一个html控件的值,比如input 控件值,当我们把表单提交到服务器后, 页面再刷新回来的时候, input里面的数据已经被清空. 这是因为we ...

  8. HttpApplication事件ASP.NET页面周期

    学习吧少年........................... 修改中........... 当一次请求到达IIS 1.http.sys将请求发送到指定的应用程序池. 2.应用程序池再将请求交给池中 ...

  9. .net面试问题汇总(转)

    用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层? 答: 从下至上分别为:数据访问层.业务逻辑层(又或成为领域层).表示层 数据访问层:有时候也称为是持久层,其 ...

最新文章

  1. 计算机图学测试题及答案,《计算机图形学》练习测试题及参考答案
  2. 互联网晚报 | 3月15日 星期二 |​ 特斯拉Model 3高性能版和Model Y长续版再涨价;字节成都成立光合科技公司...
  3. Github 1300+ 星!旷视开源的深度强化学习绘画智能体论文解读
  4. 使用正则表达式把关键字替换加粗
  5. JavaWeb开发Servlet学习
  6. Matlab求矩阵均值
  7. 【U盘量产】你的U盘坏了吗
  8. 判断经纬度是否落在中国地图上
  9. 利用Anaconda Prompt在Jupter notebook中安装包
  10. Python-qqbot实现QQ群翻译机器人
  11. 关闭打印机和无线服务器,打印机无线连接断开了怎么办?
  12. Bash cp 命令详解
  13. 基金直销账户体系介绍
  14. 成功解决Unexpected end of JSON input while parsing near的问题
  15. SOA为什么不“香”了?| 建设数据中台系列(三)
  16. 2022AP微积分AB北美卷FRQ已放出,附考情分析
  17. Kubernetes学习笔记(二)------什么是Kubernetes
  18. windows 删除文件夹 拒绝访问
  19. 转专业选择计算机的理由,转专业的理由如何描写?
  20. virtualbox 创建桥接网络_virtualbox下linux虚拟机的网络配置——桥接网络

热门文章

  1. c++中的list用法
  2. android界面不可见键盘隐藏功能,Android中点击隐藏软键盘最佳方法
  3. 利用Matlab比较IIR和FIR,细说IIR滤波器和FIR滤波器的区别
  4. ajax jq 图片上传请求头_如何使用js或jQuery向Ajax请求添加自定义HTTP头?
  5. 第二讲 ODE欧拉数值方法
  6. MyBatis中调用存储过程和函数
  7. javascript原型对象、原型链、构造函数
  8. Runtime之IMP指针,isa指针
  9. php 下载文件的函数
  10. 在Linux下使用screen使用退出远程终端后程序依然自动进行