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. response.sendRedirect(location)与rd.forward()区别

    在Java Web开发中,经常会用到跳转页面的方法,一般有下面两种方法. HttpServletResponse response = new HttpServletResponse(); respo ...

  2. 建筑抢修 BZOJ 1029

    建筑抢修 [问题描述] 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修 ...

  3. 微服务网关实战——Spring Cloud Gateway

    导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...

  4. 另一篇xtion、kinect选择比较(openni下)

    小小Xtion开箱测评!!2012年03月12日 19:52:55 原文:http://page.renren.com/601107241/note/811764499 ASUS Xtion Pro ...

  5. 洛谷 P3865 【模板】ST表

    P3865 [模板]ST表 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为  ...

  6. 【Java TCP/IP Socket】应用程序协议中消息的成帧与解析(含代码)

    程序间达成的某种包含了信息交换的形式和意义的共识称为协议,用来实现特定应用程序的协议叫做应用程序协议.大部分应用程序协议是根据由字段序列组成的离散信息定义的,其中每个字段中都包含了一段以位序列编码(即 ...

  7. Spring中Beans的自动装配概述

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/beans-autowiring.html: 在之前的做法上会参照这样的顺序:1.使用<bea ...

  8. flask的debug模式下,网页输入pin码进行调试

    网站后端Python+Flask .FLASK调试模式之开启DEBUG与PIN使用? 自动加载: # 方式一 1 2 if __name__ == '__main__':     app.run(ho ...

  9. 关于HTML中文乱码问题

    系统:ubuntu 14.04 软件:bluefish 一.乱码原因 1.不同编码内容混杂:HTML乱码是因为html编码问题照成(常见gb2312与utf-8两种编码内容同一时候存在照成) 2.未设 ...

  10. pomelo加入定时任务

    需求:在arenaserver下添加一个rank定时任务,每一分钟对对玩家进行一次排行. 首先在game-server/app/servers/arena文件夹下添加cron文件夹. 在game-se ...