【.net 深呼吸】设置序列化中的最大数据量
欢迎收看本期的《老周吹牛》节目,由于剧组严重缺钱,故本节目无视频无声音。好,先看下面一个类声明。
[DataContract]
public class DemoObject
{
[DataMember]
public double Part1 { get; set; }
[DataMember]
public int Part2 { get; set; }
[DataMember]
public byte Part3 { get; set; }
[DataMember]
public string Part4 { get; set; }
}
这个类是老周随便瞎写的,没有特别内涵,只是用来做做实验而已。注意类型上应用的attribute,它被定义为数据协定。
下面是重点,对这个类的实例进行序列化,所以,我们先得new一个实例。
DemoObject obj = new DemoObject
{
Part1 = 33.0065d,
Part2 = ,
Part3 = ,
Part4 = "kill dog"
};
然后,可以序列化了。
DataContractSerializerSettings settings = new DataContractSerializerSettings
{
MaxItemsInObjectGraph = 3 }; DataContractSerializer szr = new DataContractSerializer(obj.GetType(), settings);
szr.WriteObject(stream, obj);
注意,在序列化前,我创建了一个DataContractSerializerSettings对象,并把一个名为 MaxItemsInObjectGraph 的属性设置为3,这是啥含义呢,别急,咱们看看这段代码在运行时会发生什么意外。

从上面的高清图中大家看到了,它说 MaxItemsInObjectGraph = 3,这尺码太小了,穿不上。
MaxItemsInObjectGraph 值用来设置实例对象在序列化的时候,能够处理数据项的最大值。
那么,DemoObject 类在序列化时,到底会有多少个数据项呢,怎么计算的呢。
来,我们一层一层地剥皮。
第一层:DemoObject对象本身,算1个。
第二层:它有四个属性,而且每个属性的类型都是基础类型(string、int等),基础类型都视为单个数据项,所以此层有4项数据。
好,两层加起来就是 = 5,也就是说,要序列化 DemoObject 类对象,序列化程序需要处理5个数据项,因此,3太小了,咱们换个大号的,把它改为5。
DataContractSerializerSettings settings = new DataContractSerializerSettings
{
MaxItemsInObjectGraph =
};
这么一改,就可以正常序列化了。
如果还不过瘾,咱们继续探讨。
来,看看下面这个类。
[DataContract]
public class Something
{
[DataMember]
public List<double> Items { get; private set; } public Something()
{
Items = new List<double>();
}
}
你猜猜,它在序列化时要处理多少项数据?
好,咱们设置最大值为3,试试看。
Something obj = new Something();
obj.Items.Add(0.001d);
obj.Items.Add(-99.99d); DataContractSerializerSettings settings = new DataContractSerializerSettings
{
MaxItemsInObjectGraph =
}; DataContractSerializer sz = new DataContractSerializer(obj.GetType(), settings);
sz.WriteObject(stream, obj);
运行上面代码,你会收到异常信息,这说明,3个数据项是不够的。
那么,现在咱们来数一下:
第一层,Something 类实例自身算是1个对象。
第二层,Something类中 有个Items属性,它是一个List<T>对象,算是1个。
第三层,list中有两个double值,算是2个对象。
最后,序列化要处理的对象数 = 1 + 1 + 2 = 4。
所以,把上面代码改一下,改为4,或者大于4都行,因为 MaxItemsInObjectGraph 设置的是取大项数,你设100也行。
DataContractSerializerSettings settings = new DataContractSerializerSettings
{
MaxItemsInObjectGraph =
};
这样就可以正常序列化了。序列化生成以下XML。
<Something xmlns="……" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Items xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:double>0.001</a:double>
<a:double>-99.99</a:double>
</Items>
</Something>
下面咱们来个变态级别的,你能数出来吗?
[DataContract]
public class Employee
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
} [DataContract]
public class PartMent
{
[DataMember]
public string PartName { get; set; }
[DataMember]
public Employee Manager { get; set; }
[DataMember]
public List<Employee> Members { get; set; }
}
注意,这两个数据协有关联,PartMent实例会引用N个Employee 实例。而且,PartMent 中有个list类型的属性,所以,序列化的数据项数量是变动的,因为list中可以添加X个对象。
我们先把可以确定的对象数算出来,对于可变的,我们就用一个x来指代。
1,PartMent 自身算1个。
2,PartName 属性是字符串类型,算1个。
3、Manager 属性是Employee类型。Employee类好计算吧,类实例本身1个,Name 和 Age 属性都是基础类型,共2个,加起来即一个Employee实例会包含 3 个数据项。
4、Members 属性是个List<T>,list 实例自身算 1 个,而里面每个Employee实例,刚刚算过,是3个,如果有x个实例,就是 3 × x 个数据项, 合计为 1 + 3x 个数据项。
总结上面的分析,得出一个通用公式: n = 1+1+3+(1+3x) ,再整理一下就是:n = 6 + 3x。
好,来个代码演示。
PartMent pmt = new PartMent();
pmt.PartName = "人渣部门";
pmt.Manager = new Employee { Name = "老鬼", Age = };
// 1 + 1 + (1 + 2) = 5 List<Employee> emps = new List<Employee>();
emps.Add(new Employee { Name = "小李", Age = });
emps.Add(new Employee { Name = "小刘", Age = });
emps.Add(new Employee { Name = "小杜", Age = });
pmt.Members = emps;
// (3 * 3) + 1 = 10 DataContractSerializerSettings settings = new DataContractSerializerSettings
{
MaxItemsInObjectGraph =
}; DataContractSerializer sz = new DataContractSerializer(pmt.GetType(), settings);
sz.WriteObject(stream, pmt);
上面代码中,在 list 里面放了 3 个 Employee 实例,套上面得到的公式 6+3*3 = 15,所以,这个实例序列化后会处理 15 个数据项,生成的XML如下:
<PartMent xmlns="……" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Manager>
<Age>55</Age>
<Name>老鬼</Name>
</Manager>
<Members>
<Employee>
<Age>25</Age>
<Name>小李</Name>
</Employee>
<Employee>
<Age>40</Age>
<Name>小刘</Name>
</Employee>
<Employee>
<Age>37</Age>
<Name>小杜</Name>
</Employee>
</Members>
<PartName>人渣部门</PartName>
</PartMent>
怎么样,刺激吧。
当然了,我只是为了演示,就设置为15个,其实,最大值一般不会这么小,设置几百个也可以。序列化选项之所以会有这个最大值的限制数值,是为了防止一些不良青年搞恶意破坏,比如,如果某个客户端要向服务器提交数据,数据内容自然是要先序列化,然后才能通过网络发送,尤其像web服务调用这种情况。你想想,如果不设置个限制值,别有用心的人,可以故意地弄一个特大对象来攻击服务器。
OK,今天的吹牛节目就此结束了,下次有空再见。
【.net 深呼吸】设置序列化中的最大数据量的更多相关文章
- 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)
原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...
- asp.net中绘制大数据量的可交互的图表
在一个asp.net项目中要用到能绘制大数据量信息的图表,并且是可交互的(放大.缩小.导出.打印.实时数据),能够绘制多种图形. 为此进行了多方调查预研工作,预研过微软的MsChart图表组件.基于j ...
- BloomFilter中保存的数据量
结果 /** * @author WeiJiQian * BF_CARDINAL_THRESHOLD BF_FALSE_POSITIVE_RATE 保存的数据量 * 100,0000 0.01 391 ...
- 【.net 深呼吸】序列化中的“引用保留”
假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据. 看看下面两个类. [DataContract] public class 帅 ...
- MySQL设置表中字段的数据唯一性
mysql设置数据库表里的某个字段的数据是唯一的 ALTER TABLE 表名 ADD unique(`表中的字段`)
- Kendo UI中TreeView 放入tabstrip中,大数据量时超过边框的解决方案。
参考http://www.kendoui.com/forums/ui/tabstrip/tabstip-with-treeview-treeview-breaking-out-of-tabstrip. ...
- MS Sql Server 查询数据库中所有表数据量
方法一: SELECT a.name,b.rows FROM sysobjects a INNER JOIN sysindexes b ON a.id=b.id ,) AND a.Type='u' O ...
- 关于MySQL中查询大数据量的情况下分页limit的性能优化
https://blog.csdn.net/weixin_37848710/article/details/80772725
- 采用Kettle分页处理大数据量抽取任务
作者:Grey 原文地址: http://greyzeng.com/2016/10/31/big-data-etl/ 需求: 将Oracle数据库中某张表历史数据导入MySQL的一张表里面. 源表(O ...
随机推荐
- ExtJS 4.2 评分组件
上一文章是扩展ExtJS自带的Date组件.在这里将创建一个评分组件. 目录 1. 介绍 2. 示例 3. 资源下载 1. 介绍 代码参考的是 Sencha Touch 2上的一个RatingStar ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- 数据库的快照隔离级别(Snapshot Isolation)
隔离级别定义事务处理数据读取操作的隔离程度,在SQL Server中,隔离级别只会影响读操作申请的共享锁(Shared Lock),而不会影响写操作申请的互斥锁(Exclusive Lock),隔离级 ...
- CSS Position 定位属性
本篇文章主要介绍元素的Position属性,此属性可以设置元素在页面的定位方式. 目录 1. 介绍 position:介绍position的值以及辅助属性. 2. position 定位方式:介绍po ...
- 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二)
前言 文章 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 中,已经完成对 gulp 的安装,由于是window环境,文中特意提到了可以通过安装 gitbash 来代替 ...
- Git命令总结
本文转载自345大神.... 查看原文 先上个图形化界面GIT工具 SourceTree下载链接 windows版 1.8.3 & Mac版 2.2.4 链接: http://pan.baid ...
- 谈谈一些有趣的CSS题目(六)-- 全兼容的多列均匀布局问题
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 【原创经验分享】WCF之消息队列
最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...
- CSS垂直居中的11种实现方式
今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...
- 机器指令翻译成 JavaScript —— No.2 跳转处理
上一篇,我们发现大多数 6502 指令都可以直接 1:1 翻译成 JS 代码,但除了「跳转指令」. 跳转指令,分无条件跳转.条件跳转.从另一个角度,也可分: 静态跳转:目标地址已知 动态跳转:目标地址 ...