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 ...
随机推荐
- vs2015插件推荐 Productivity Power Tools 2015
vs2015插件推荐 Productivity Power Tools 2015 官网网址:https://marketplace.visualstudio.com/items?itemName=Vi ...
- 淘金(bzoj 3131)
Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹 ...
- *LOJ#2322. 「清华集训 2017」Hello world!
$n \leq 50000$的树,有点权$\leq 1e13$,$q \leq 400000$次操作,有两种操作:从$s$跳到$t$每次$k$步,不到$k$步直接跳到$t$,每次把经过的点取根号:同样 ...
- NFV产品如何才能走向规模商用
作者简介:王晔,烽火通信科技股份有限公司ICT网络产品线NFV产品总监,高级工程师,研究方向为SDN\NFV\MEC\AI\光通信. 自2013年AT&T率先提出DOMAIN 2.0网络转型计 ...
- Java 一个?格式的解决
用Java 出现了这样的一个问题?好几天都没解决掉 然后最近一直找资料 截个图: 本来格式中时没有这个?号的,代码里面用GBK和utf-8都不能解决. 即使我加了 Str.trim(Str)去除 字符 ...
- Java抓屏程序代码
原文:http://www.open-open.com/code/view/1422262655200 import java.awt.Dimension; import java.awt.Recta ...
- 【gradle】mac上安装gradle
根据gradle官网指导,一步一步安装即可 https://gradle.org/install/ 或者,如果你没有办法墙出去,或者本地使用命令下载gradle比较慢的话,可以采用下面的方式 ==== ...
- iinflux数据库使用
特殊用法: http://blog.fatedier.com/2016/07/05/research-of-time-series-database-influxdb/ 创建表及表中的key和valu ...
- jQuery.ajax()方法中參数具体解析
前言 在项目开发中,为了实现异步向服务端发起请求,最常常使用的就是jQuery.ajax方法了.刚開始需求比較简单,调用jQuery.ajax方法时要传的參数也就那几个常见的參数:url/data/d ...
- Linux常用C函数-接口处理篇(网络通信函数)
接口处理篇accept,bind,connect,endprotoent,endservent,getsockopt,htonl,htons,inet_addr,inet_aton,inet_ntoa ...