WCF-省略DataContract标记
来源:互联网 发布:js 老虎机抽奖效果 编辑:程序博客网 时间:2024/05/22 14:38
写过WCF程序的朋友都知道,在对实体对象在WCF和客户端之间传递时一定要加DataContract标记这个类并用DataMember来标记要序列化的属性/字段。这一直正确,只是在.NET Framework 3.5 SP1中新添加了一些支持,那就是你不一定必须对这些实体对象应用DataContract标记,这被称作对plain old C# objects(POCO)的序列化支持。
Serializable标记大家都很熟悉,它是XmlSerializer的标记,在WCF中其实很少用这个标记,因为我们WCF用的是DataContractSerializer,对应的标记也是DataContract。但对于SP1来说,Serializable也以XmlSerializer的规则被正常解析,其对应的Mapping规则和Serializer对应,其公有可读写字段被默认序列化。当然,你也可以通过XmlElement等标记来做高级映射,但这不是我们这里需要谈及的内容。
DataContract对应的序列化处理叫做DataContactSerializer。在WCF中一旦一个类被标记为DataContract,那么只有标记为DataMember的字段/属性才会被序列化。但如果你使用DataContract标记,那么DataContractSerializer默认将所有公有可读写字段序列化(这和Serializable是一样的)。假设我们有这么一个类:
public class Person
{
public Person()
{ }
public Person(string strId, string strName)
{
this.Id = strId;
this.Name = strName;
}
private string strid;
public string Id { get { return strid; } set { strid = value; } }
public string Name;
public Person Spouse;
private int Number = 343;
}
对于DataSerializer来说,他和给所有公有属性添加DataMember并将类标记为DataContract是一样的。下面的一段程序分别将一个Person的实例对象分别用XmlSerializer和DataContractSerializer来序列化:
static void Main(string[] args)
{
Person p = new Person();
p.Id = "123";
p.Name = "Aaron";
p.Spouse = new Person();
p.Spouse.Id = "456";
p.Spouse.Name = "Monica";
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
using (FileStream fs = new FileStream("person.xml", FileMode.Create))
{
dcs.WriteObject(fs, p);
}
XmlSerializer xs = new XmlSerializer(typeof(Person));
using (FileStream fs = new FileStream("person_serialization.xml", FileMode.Create))
{
xs.Serialize(fs, p);
}
}
对于序列化后的内容我们得到的结果其实是一样的:仅有公有属性/字段被序列化
<Person xmlns="http://schemas.datacontract.org/2004/07/Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Id>123</Id>
<Name>Aaron</Name>
<Spouse>
<Id>456</Id>
<Name>Monica</Name>
<Spouse i:nil="true"/>
</Spouse>
</Person>
但如果你使用了DataContract来标记这个类,却没有使用DataMember,那么没有任何属性/字段被序列化:
[DataContract]
public class Person
{
private string strid;
public string Id { get { return strid; } set { strid = value; } }
public string Name;
public Person Spouse;
private int Number = 343;
}
<Person xmlns="http://schemas.datacontract.org/2004/07/Serialization" xmlns:i=http://www.w3.org/2001/XMLSchema-instance />
对于将类标记成Serializable,DataContractSerializer的序列化可能让我们觉得有些奇怪,它本质上是将所有可读写字段序列化,这其中还包括私有字段。例如我们将Person类用[Serializable]标记,执行程序,我们会得到以下的结果:
<Person xmlns="http://schemas.datacontract.org/2004/07/Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>Aaron</Name>
<Number>0</Number>
<Spouse>
<Name>Monica</Name>
<Number>0</Number>
<Spouse i:nil="true"/>
<_id>456</_id>
</Spouse>
<_id>123</_id>
</Person>
一个简单的WCF程序来看看来检验一下是否正确。在Contract生命中我们并不需要制定任何的标记,并声明一个得到DeskMesh的方法:
[ServiceContract]
public interface IDeskMesh
{
[OperationContract]
DeskMesh GetDeskMesh(string name);
}
public class DeskMesh
{
private int _id;
private int Number = 4433;
public int ID
{
get { return _id; }
set { _id = value; }
}
public string Name { get; set; }
public string Description { get; set; }
public string Unit { get; set; }
public float Price { get; set; }
public DateTime Created { get; set; }
public override string ToString()
{
return string.Format("ID:{4}"r"nName: {0}"r"nUnit:{1}"r"nPrice:{2}"r"nCreated:{3}"r"nNumber:{5}",
Name, Unit, Price, Created.ToShortDateString(),ID.ToString(),Number.ToString());
}
}
客户端调用,会返回一个DeskMesh的实例。通过结果,你会发现这完全和你标记DataContract的实体在WCF两端传递一模一样。
void Main(string[] args)
{
Console.WriteLine("Requesting...");
ServiceClient client = new ServiceClient();
DeskMesh mesh = client.GetDeskMesh("");
Console.WriteLine(mesh.ToString());
Console.WriteLine("press any key to continue...");
Console.Read();
}
总结一下吧,WCF中应用各个标记时所作的序列化处理:
1. 不给任何标记将会做XML映射,所有公有属性/字段都会被序列化
2. [Serializable]标记会将所有可读写字段序列化
3. [DataContract]和[DataMember]联合使用来标记被序列化的字段
- WCF-省略DataContract标记
- WCF-省略DataContract标记
- WCF - DataContract 继承
- WCF DataContract and DataMember
- WCF数据契约(DataContract)
- WCF学习笔记-DataContract等价性
- Difference between datacontract and messagecontract in wcf
- WCF中 DataContract、DataMember的作用
- HTML5标记省略 语法规则
- HTML5标记省略 语法规则
- Silverlight Wcf 获取集合数据并绑定(DataContract,DataMember)
- CSS全兼容实现文字省略标记
- 省略PHP结束标记 “?>”的好处
- css 同行文字超长显示省略标记
- 文本溢出显示省略标记'...'的bug
- HTML5可以省略全部标记的元素
- HTML5可以省略结束标记的元素
- 【HTML5】可以省略标记的元素
- 在Linux上使用的10种云备份方案
- Acm课程总结
- 大学生如何keep energetic
- 小凡的Linux主机与时间服务器同步记录
- ajax跨域post方式
- WCF-省略DataContract标记
- UNIX/Linux 下终端控制字符
- JSP-导入taglib 出现classNotFound异常
- 近期javaWEB项目总结 1
- nginx服务器安装及配置文件详解
- WebService学习总结 三 利用本地wsdl文档生成客户端代码和TCP/IP工具监听请求
- NYOJ-7-街区最短路径问题
- 书单集合
- MySQL数据类型