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. angular中ng-repeat去重

    [html] view plain copy print?在CODE上查看代码片派生到我的代码片 <div ng-app="myApp" ng-controller=&quo ...

  2. 手动实现jQuery的toggle()效果

    有时候我们希望实现toggle()切换效果,但是切换的同时需要完成一些其他要做的事情.所以我们需要对jQuery的toggle()函数进行改造. 下面好test2()函数就是一个实现toggle效果的 ...

  3. 标准C程序设计七---27

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  4. Java游戏服务器搭建

    一.前言 此游戏服务器架构是一个单服的形式,也就是说所有游戏逻辑在一个工程里,没有区分登陆服务器.战斗服务器.世界服务器等.此架构已成功应用在了多款页游服务器 .在此框架中没有实现相关业务逻辑,只有简 ...

  5. 2017-10-28-morning-清北模拟赛

    T1 立方数(cubic) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是 ...

  6. 计算机操作系统处理机调度读后感—–关于进程概念的剖析。从RING3到RING0(32位操作系统)

    计算机操作系统处理机调度读后感: 笔者在看操作系统西安电子科技大学那本书的时候,初次感觉本科教的不会太难,所以没有认真的看,但是随后这本书讲的刷新了我的世界观.这本书居然是ring0级别的,这时不禁吐 ...

  7. Spark学习(一) Spark初识

    一.官网介绍 1.什么是Spark 官网地址:http://spark.apache.org/ Apache Spark™是用于大规模数据处理的统一分析引擎. 从右侧最后一条新闻看,Spark也用于A ...

  8. SystemTap 静态探针安装包

     yum install systemtap-sdt-devel 

  9. BroadcastReceiver详解(一)

    今天我们来讲一下Android中BroadcastReceiver的相关知识. BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播. 在And ...

  10. csu1527: Bounty Hunter

    Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status id=134 ...