现在的位置: 主页 > 新闻中心 > 文章列表

WCF 序列化与反序列化复杂类型(DataContractSerializ

作者:厦工楚胜(湖北)专用汽车制造有限公司 来源:www.szzq168.com 发布时间:2017-09-06 10:29:31
 

WCF 序列化与反序列化复杂类型(DataContractSerializer)

.NET的类型可以分为两种:声明类型和真实类型。我们提倡面向接口的编程,对象的真实类型往往需要在运行时才能确定,在编程的时候往往只需要指明类型的声明类型,比如类型实现的接口或者抽象类。当我们使用基于接口或者抽象类创建的DataContractSerializer去序列化一个实现了该接口或者继承该抽象类的实例的时候,往往会因为对对象的真实类型无法识别造成不能正常地序列化。

现在,我们定义两个带数据协定的类——ActionInfo和ActionParameterInfo:

/// /// 动作信息 /// [DataContract(Namespace = )] [KnownType(GetKnowTypes)] //[KnownType(GetKnowTypesQuote)] public class ActionInfo { private string actionName; /// /// 动作名称 /// [DataMember] public String ActionName { get { return actionName; } set { actionName = value; } } private string actionId; /// /// 动作唯一标识 /// [DataMember] public String ActionId { get { return actionId; } set { actionId = value; } } private Dictionary actionParameters; /// /// 参数信息 /// [DataMember] public Dictionary ActionParameters { get { if (actionParameters == null) { actionParameters = new Dictionary(); } return actionParameters; } set { actionParameters = value; } } static Type[] GetKnowTypes() { return new Type[] { typeof(Dictionary) }; } //[DataMember] //public object Quote; //static Type[] GetKnowTypesQuote() //{ // return new Type[] { typeof(Dictionary) }; //} } /// /// 动作参数 /// //[DataContract(Namespace = )] [DataContract] public class ActionParameterInfo { private bool parameterAllowDBNull; /// /// 参数是否允许为空 /// //[DataMember(Name = 参数是否允许为空, Order = 2)] [DataMember] public bool ParameterAllowDBNull { get { return parameterAllowDBNull; } set { parameterAllowDBNull = value; } } private ActionInfoParameterCategoryEnum parameterCategory; /// /// 参数分类 /// //[DataMember(Name = 参数分类, Order = 3)] [DataMember] public ActionInfoParameterCategoryEnum ParameterCategory { get { return parameterCategory; } set { parameterCategory = value; } } private object parameterValue; /// /// 参数值 /// //[DataMember(Name = 参数值, Order = 1)] [DataMember] public object ParameterValue { get { return parameterValue; } set { parameterValue = value; } } private string parameterCode; /// /// 参数编号(未添加DataMember标识) /// public string ParameterCode { get { return parameterCode; } set { parameterCode = value; } } public enum ActionInfoParameterCategoryEnum { [Description(普通类型)] CommonType = 0, [Description(事件源)] EventSource = 1, [Description(事件参数)] EventArgument = 2, [Description(控件ID)] ControlId = 3, [Description(表单ID)] FormId = 4 }

在代码中添加以下代码填充实体类:

ActionInfo ac = new ActionInfo(); ac.ActionId = ActionId + Guid.NewGuid().ToString(); ac.ActionName = ActionName + Guid.NewGuid().ToString(); ac.ActionParameters = new Dictionary(); for (int i = 0; i < 2; i++) { ActionParameterInfo ap = new ActionParameterInfo(); ap.ParameterAllowDBNull = false; ap.ParameterCategory = ActionInfoParameterCategoryEnum.CommonType; ap.ParameterValue = Guid.NewGuid(); ac.ActionParameters.Add(ap.ParameterValue.ToString(), ap); } 测试序列化: string ss = PubXmlSerializer.ToXMLString(ac); 生成的xml如下: ActionIdb9da9159-068e-4cae-9810-5e2ca4f0a87f ActionName70737f3b-1672-437e-8ad5-543038ac62b4 4e059222-023f-40aa-b08e-42e377570092 false CommonType 4e059222-023f-40aa-b08e-42e377570092 5c528920-a7c6-4fc4-8632-a2f083d43676 false CommonType 5c528920-a7c6-4fc4-8632-a2f083d43676

从xml看到:

DataContractSerializer在默认的情况下采用了如下的序列化规则。
1、XML的根节点名称为数据契约类型的名称。
2、默认的命名空间采用的格式为 (数据契约类型的命名空间)。
3、只有显示地应用了DataMemberAttributue特性的字段或属性才能作为数据成员参与序列化。
4、所有数据成员均以XML元素的形式被序列化。
5、序列化后数据成员在XML中的次序采用这样的规则:父类数据成员在前,子类数据成员在后;定义在同一个类型中的数据成员按照字母排序。

如果默认序列化后的xml结构不能满足我们的需求,则可以通过DataContractAttribute和DataMenmberAttribute这两个特性对其进行修正。在下面我们通过DataContractAttribute特性设置了数据契约的名称和命名空间,通过DataMenmberAttribute特性的Name属性为Name和Birthday两个属性设置不同于属性名称的数据成员名称,并通过Order控制数据成员的先后次序。

修改ActionParameterInfo类:

/// /// 动作参数 /// [DataContract(Namespace = )] public class ActionParameterInfo { private bool parameterAllowDBNull; /// /// 参数是否允许为空 /// [DataMember(Name = 参数是否允许为空, Order = 2)] public bool ParameterAllowDBNull { get { return parameterAllowDBNull; } set { parameterAllowDBNull = value; } } private ActionInfoParameterCategoryEnum parameterCategory; /// /// 参数分类 /// [DataMember(Name = 参数分类, Order = 3)] public ActionInfoParameterCategoryEnum ParameterCategory { get { return parameterCategory; } set { parameterCategory = value; } } private object parameterValue; /// /// 参数值 /// [DataMember(Name = 参数值, Order = 1)] public object ParameterValue { get { return parameterValue; } set { parameterValue = value; } } private string parameterCode; /// /// 参数编号(未添加DataMember标识) /// public string ParameterCode { get { return parameterCode; } set { parameterCode = value; } } 再次序列化,xml结构如下: ActionIdd95e434d-4f13-49b7-859e-a7964f468d70 ActionNamef750900a-42fe-4586-9688-768cdefd4d78 560e9e05-2c7d-482a-89f5-ea200bbe42b3 <参数值 i:type=b:guid xmlns:b=http://schemas.microsoft.com/2003/10/Serialization/>560e9e05-2c7d-482a-89f5-ea200bbe42b3 <参数是否允许为空>false <参数分类>CommonType eac9bc48-be0c-4c36-92d0-8f392f010516 <参数值 i:type=b:guid xmlns:b=http://schemas.microsoft.com/2003/10/Serialization/>eac9bc48-be0c-4c36-92d0-8f392f010516 <参数是否允许为空>false <参数分类>CommonType 有木有发现DataMember中Name与Order的作用啊

小注:

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:荆门SEO http://jingmen.raoyu.net

  • 上一篇:python学习笔记二
  • 下一篇:最后一页