DataContractAttribute.IsReference
IsReference property in data contract
It determines how objects are serialized, by default, IsReference=false.
Setting IsReference = true allows the serialization of trees of objects that can reference each other. So with a list of Employees that each have a property for Manager (who is also an Employee), a reference to the Manager for each Employee can be held rather than embedding the Manager within each Employee node:
IsReference=false would produce:
<Employee>
<Manager i:nil=“true“ />
<Name>Kenny</Name>
</Employee>
<Employee>
<Manager>
<Manager i:nil=“true“ />
<Name>Kenny</Name>
</Manager>
<Name>Bob</Name>
</Employee>
<Employee>
<Manager>
<Manager i:nil=“true“ />
<Name>Kenny</Name>
</Manager>
<Name>Alice</Name>
</Employee>
Where as IsReference=true would produce:
<Employee z:Id=“i1“ xmlns:z=“http://schemas.microsoft.com/2003/10/Serialization/“>
<Manager i:nil=“true“ />
<Name>Kenny</Name>
</Employee>
<Employee z:Id=“i2“ xmlns:z=“http://schemas.microsoft.com/2003/10/Serialization/“>
<Manager z:Ref=“i1“ />
<Name>Bob</Name>
</Employee>
<Employee z:Id=“i3“ xmlns:z=“http://schemas.microsoft.com/2003/10/Serialization/“>
<Manager z:Ref=“i1“ />
<Name>Alice</Name>
</Employee>
Snippets taken from this weblog that has a full explanation along with examples of the generated XML with the property applied.
MSDN - IsReference Property provides details as well as Interoperable Object References.
DataContract Serializer and IsReference property
In .net Framework 3.5 SP1, DataContractSerializer supports by-ref object graph serialization by using the standard xsd:ID/xsd:IDREF attributes.
You can set the IsReference=true on your DataContract definition and serializer will generate XML elements with IDs/IDREFs attributes and will link them together rather embedding them inside each other(default behavior).
Also if you examine the XSD generated by WCF as part of the metadata export, it will also contain the standard ID/IDREF xml schema attributes. Because of this, xml can be correctly parsed and understood by any framework in a standard way.
This change will enable serialization of object graphs having circular references (which wasn’t possible previously – at least not without writing custom code) and will also reduce the size of the serialized xml.
Let’s examine this change using the following DataContract definition:
[DataContract]
public class Employee
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Employee Manager { get; set; }
}
[DataContract]
public class Department
{
[DataMember]
public List<Employee> Staff { get; set; }
[DataMember]
public string DeptName { get; set; }
}
Now if we serialize following Department object using DataContractSerializer
var kenny = new Employee() { Name = "Kenny" };
var bob = new Employee() { Name = "Bob", Manager = kenny };
var alice = new Employee() { Name = "Alice", Manager = kenny };
var ahmed = new Employee() { Name = "Ahmed", Manager = kenny };
var dept = new Department() { DeptName = "RandD", Staff = new List<Employee>() { kenny, bob, alice, ahmed } };
DataContractSerializer dcs = new DataContractSerializer(typeof(Department));
var ms = new MemoryStream();
dcs.WriteObject(ms, dept);
ms.Seek(0, SeekOrigin.Begin);
var sr = new StreamReader(ms);
var xml = sr.ReadToEnd();
We will get this xml.
<Department xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication2" xmlns:i="http://www.w3.org/2001/XMLSchemainstance">
<DeptName>RandD</DeptName>
<Staff>
<Employee>
<Manager i:nil="true" />
<Name>Kenny</Name>
</Employee>
<Employee>
<Manager>
<Manager i:nil="true" />
<Name>Kenny</Name>
</Manager>
<Name>Bob</Name>
</Employee>
<Employee>
<Manager>
<Manager i:nil="true" />
<Name>Kenny</Name>
</Manager>
<Name>Alice</Name>
</Employee>
<Employee>
<Manager>
<Manager i:nil="true" />
<Name>Kenny</Name>
</Manager>
<Name>Ahmed</Name>
</Employee>
</Staff>
</Department>
You can see manager Kenny is included in all Employee objects, essentially a by-value inclusion. Now if we change the declaration of Employee class to following:
[DataContract(IsReference = true)]
public class Employee
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Employee Manager { get; set; }
}
With above change, you will get following different xml.
<Department xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication2" xmlns:i="http://www.w3.org/2001/XMLSchemainstance">
<DeptName>R&D</DeptName>
<Staff>
<Employee z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Manager i:nil="true" />
<Name>Kenny</Name>
</Employee>
<Employee z:Id="i2" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Manager z:Ref="i1" />
<Name>Bob</Name>
</Employee>
<Employee z:Id="i3" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Manager z:Ref="i1" />
<Name>Alice</Name>
</Employee>
<Employee z:Id="i4" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Manager z:Ref="i1" />
<Name>Ahmed</Name>
</Employee>
</Staff>
</Department>
In attribute-free (POCO) world:
you can use a different ctor, taking a boolean flag, to toggle by-val/by-ref serialization.
To enable circular references for operation or service scope, you can use custom behaviors etc. Essentially you need the ability to hook into serializer instantiation process and create the instance using above overload:
1. Subclass DataContractSerializerOperationBehavior
2. Ovverride CreateSerializer method
3. Create a new DCS instance passing true to preserveObjectReferences param.
class DataContractSerializerOperationBehaviorEx : DataContractSerializerOperationBehavior
{
public DataContractSerializerOperationBehaviorEx(OperationDescription operation):base(operation)
{
}
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes, this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject, true, this.DataContractSurrogate);
}
public override XmlObjectSerializer CreateSerializer(Type type, System.Xml.XmlDictionaryString name, System.Xml.XmlDictionaryString ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes, this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject, true, this.DataContractSurrogate);
}
}
DataContractAttribute.IsReference的更多相关文章
- ASP.NET MVC4中调用WEB API的四个方法
http://tech.it168.com/a2012/0606/1357/000001357231_all.shtml [IT168技术]当今的软件开发中,设计软件的服务并将其通过网络对外发布,让各 ...
- ASP.NET MVC4 json序列化器
ASP.NET MVC4中调用WEB API的四个方法 2012年06月07日00:05 it168网站原创 作者:廖煜嵘 编辑:景保玉 我要评论(0) [IT168技术]当今的软件开发中,设计软件的 ...
- mvc4项目数据库优先的尝试
对于mvc代码优先原则,感觉真不知道为什么硬要设计这种模式,代码优先使得每次运行程序都要重建数据库,现实中这种模式有什么用呢. 数据库优先可能有好多方式,看了好久才做出来一种比较简单的.通过先添加一个 ...
- C#综合揭秘——分部类和分部方法
在面向对象的“封装闭合性”开发原则中,一向提倡的是把独立的功能封装在一个类里面的!但从Visual Studio 2005开发,系统提供了一个分部类的开发方式一直受到争议,很多人认为把同一类的功能分布 ...
- 前端框架MVVM是什么(整理)
前端框架MVVM是什么(整理) 一.总结 一句话总结:vm层(视图模型层)通过接口从后台m层(model层)请求数据,vm层继而和v(view层)实现数据的双向绑定. 1.我大前端应该不应该做复杂的数 ...
- 架构-MVVM:MVVM核心概念
ylbtech-架构-MVVM:MVVM核心概念 1.返回顶部 1. MVVM模式是Model.View.ViewModel的简称,最早出现在WPF,现在Silverlight中也使用该模式,MVVM ...
- 找不到方法:“Boolean System.Runtime.Serialization.DataContractAttribute.get_IsReference()”的解决办法
找不到方法:“Boolean System.Runtime.Serialization.DataContractAttribute.get_IsReference()”.的解决办法站点发布后部署到了两 ...
- WCF中DataContractAttribute 类
一.这个类的作用 使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档.无法继承此类,(DataContractSerializer 用于序列化和反序列化在 Windows Commun ...
- DataContractAttribute 类
https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.datacontractattribute.aspx nam ...
随机推荐
- Maven常用参数及其说明【转:http://blog.csdn.net/wangjunjun2008/article/details/18982089】
Maven常用参数及其说明 -h,--help Display help information-am,--also-make ...
- 洛谷 P 1164 小A点菜
题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...
- #ifdef #endif #if #endif
c语言里所有以#开头的都是预编译指令,就是在正式编译之前,让编译器做一些预处理的工作. #ifdef DEBUG printf("variable x has value = %d\n&qu ...
- CODEVS_1033 蚯蚓的游戏问题 网络流 最小费用流 拆点
原题链接:http://codevs.cn/problem/1033/ 题目描述 Description 在一块梯形田地上,一群蚯蚓在做收集食物游戏.蚯蚓们把梯形田地上的食物堆积整理如下: a(1,1 ...
- GRYZY- #10. 财富
财富(treasure) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有n个小伙伴.每个小伙伴有一个身高hi. 这个游戏是这样的,LYK生活的环境是以身高 ...
- 关于Properties 集 添加数据 遍历数据
public static void fun1(){ Properties v = new Properties(); v.setProperty("a","1" ...
- Java中的网络基础
先来一张图记录一下大概思路,之后再更新具体的代码实现.基本上来说,前半部分自己会编写一个基于socket编程的多客户端dos聊天服务器,后半部分可以实现与已有的一些服务器(比如www.google.c ...
- require.js结合项目的使用心得
1.首先引入require.js 2.配置config.js文件 var $cdn_url=/'''/''/;----->指定文件一个共用的路径 require.config({ baseUrl ...
- 【C#】高级语言特有的单例模式
public class Singleton { private Singleton () { } // 变量标记为 readonly.第一次引用类的成员或创建实例时,仅仅实例化一次instance对 ...
- vue2.0 常用的 UI 库
1.mint-ui 安装: npm install mint-ui --save 使用: main.js // MintUI组件库 import MintUI from 'mint-ui' impor ...