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.

      DataContractSerializer(Type type, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate)

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的更多相关文章

  1. ASP.NET MVC4中调用WEB API的四个方法

    http://tech.it168.com/a2012/0606/1357/000001357231_all.shtml [IT168技术]当今的软件开发中,设计软件的服务并将其通过网络对外发布,让各 ...

  2. ASP.NET MVC4 json序列化器

    ASP.NET MVC4中调用WEB API的四个方法 2012年06月07日00:05 it168网站原创 作者:廖煜嵘 编辑:景保玉 我要评论(0) [IT168技术]当今的软件开发中,设计软件的 ...

  3. mvc4项目数据库优先的尝试

    对于mvc代码优先原则,感觉真不知道为什么硬要设计这种模式,代码优先使得每次运行程序都要重建数据库,现实中这种模式有什么用呢. 数据库优先可能有好多方式,看了好久才做出来一种比较简单的.通过先添加一个 ...

  4. C#综合揭秘——分部类和分部方法

    在面向对象的“封装闭合性”开发原则中,一向提倡的是把独立的功能封装在一个类里面的!但从Visual Studio 2005开发,系统提供了一个分部类的开发方式一直受到争议,很多人认为把同一类的功能分布 ...

  5. 前端框架MVVM是什么(整理)

    前端框架MVVM是什么(整理) 一.总结 一句话总结:vm层(视图模型层)通过接口从后台m层(model层)请求数据,vm层继而和v(view层)实现数据的双向绑定. 1.我大前端应该不应该做复杂的数 ...

  6. 架构-MVVM:MVVM核心概念

    ylbtech-架构-MVVM:MVVM核心概念 1.返回顶部 1. MVVM模式是Model.View.ViewModel的简称,最早出现在WPF,现在Silverlight中也使用该模式,MVVM ...

  7. 找不到方法:“Boolean System.Runtime.Serialization.DataContractAttribute.get_IsReference()”的解决办法

    找不到方法:“Boolean System.Runtime.Serialization.DataContractAttribute.get_IsReference()”.的解决办法站点发布后部署到了两 ...

  8. WCF中DataContractAttribute 类

    一.这个类的作用 使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档.无法继承此类,(DataContractSerializer 用于序列化和反序列化在 Windows Commun ...

  9. DataContractAttribute 类

    https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.datacontractattribute.aspx nam ...

随机推荐

  1. Numpy 布尔型数组

    一  给定一个列表,返回大于10的元素. 在python中,有两种方法.一种方法是循环遍历,第二种方法是使用内置函数filter() 在数组中,有更为简单的方法.即布尔型索引 布尔型索引: 将同样大小 ...

  2. 通过Idea进行Kubernetes YAML开发

    即将推出的IntelliJ IDEA 2018.1 Ultimate Edition通过全新的Kubernetes插件为Kubernetes引入了初步支持.新插件支持从v1.5到最近发布的v1.9 的 ...

  3. 【BZOJ3224】普通平衡树(splay)

    题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排 ...

  4. HDU 5015 233 Matrix(网络赛1009) 矩阵快速幂

    先贴四份矩阵快速幂的模板:http://www.cnblogs.com/shangyu/p/3620803.html http://www.cppblog.com/acronix/archive/20 ...

  5. HDU 3001 三进制 状压dp

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. ShareSDK中微信分享错误总结

    项目中用到微信分享,可向好友或朋友圈分享链接时,分享人可以打开网站,查看消息者却始终不能打开网站.试了N种方法,重写了N次分享模块,均没办法解决. 在无意中查看分享链接时发现,朋友圈里分享后,原始链接 ...

  7. ActivityGroup中监听返回按键

    如果你想使用ActivityGroup来统一管理Activity的话,当然首先这是一种很好的方法,但是如果你想在ActivityGroup里面拦截返回按键来进行统一管理的话,直接覆写onKeyDown ...

  8. PSO(Thepopularity-similarity-oplimization) modol

    PSO(Thepopularity-similarity-oplimization) modol 在这篇文章里,我们试图将社交关系构成的网络结构从纷繁复杂的具体场景.细节条件中剥离出来,单单从个体间连 ...

  9. BZOJ 1090 字符串折叠(Hash + DP)

    题目链接 字符串折叠 区间DP.$f[l][r]$为字符串在区间l到r的最小值 正常情况下 $f[l][r] = min(f[l][r], f[l][l+k-1]+f[l+k][r]);$ 当$l$到 ...

  10. T1013 求先序排列 codevs

    http://codevs.cn/problem/1013/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descr ...