如何反序列化未知的类型,而不是普通的案例

时间:2011-12-16 09:01:47

标签: c# wcf serialization known-types

我正在解决一个我没有找到答案的反序列化问题。场景是这样的:

Silverlight客户端登录服务器并返回会话对象。会话对象包含各种信息,以及名为UserSettings的集合。该集合包含一个名为propertyentity的类型,它基本上有两个属性,一个字符串和一个对象。反序列化时出现以下错误:

  

System.Runtime.Serialization.SerializationException:JSON包含一个   '__type'成员指定数据协定名称   'http://www.xyz.se/rc:ClientDifferenceRules'。解串器没有   任何映射到此合同的类型的知识。添加类型   对应于已知类型列表的“ClientDifferenceRules”    - 例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表中。您   也可以通过避免使用派生来消除这种错误   生成JSON的类型。

在session.UserSettings中发送其他propretyentities时,包含例如普通的int作为反序列化工作完美。如何告诉解串器它是什么数据类型?

ClientDifferenceRules看起来像这样:

using System;
using System.Diagnostics;
using System.Text;
using System.ComponentModel;
using System.Runtime.Serialization;

    namespace XYZ.BusinessEntities.Settings
    {

    [Serializable]
    [DataContract(Name = "ClientDifferenceRules", Namespace = Constants.Namespace)]
    [KnownType(typeof(ClientDifferenceRules))]
    public class ClientDifferenceRules :  RCBusinessBase
    {
        //private fields omitted for better readability

        public ClientDifferenceRules() : base()
        {
        }

        [DataMember]
        public override int Id
        {
            get { return _levelId;}
            set { }
        }

        [DataMember]
        public int clientId
        {
            get { return _clientId;}
            set { _clientId = value;}
        }

        [DataMember]
        public int typeId
        {
            get { return _typeId; }
            set { _typeId = value; }
        }

        [DataMember]
        public short levelId
        {
            get { return _levelId; }
            set { _levelId = value; }
        }

        [DataMember]
        public double? limitFrom
        {
            get { return _limitFrom; }
            set { _limitFrom = value; }
        }

        [DataMember]
        public double? limitTo
        {
            get { return _limitTo; }
            set { _limitTo = value; }
        }

        [DataMember]
        public string message
        {
            get { return _message; }
            set {  _message = value; }
        }

        [DataMember]
        public string description
        {
            get { return _description; }
            set { _description = value; }
        }

        [DataMember]
        public string backColor
        {
            get { return _backColor; }
            set { _backColor = value; }
        }

        [DataMember]
        public string foreColor
        {
            get { return _foreColor; }
            set {  _foreColor = value; }
        }

        [DataMember]
        public string imageUri
        {
            get { return _imageUri; }
            set {  _imageUri = value; }
        }


        [DataMember]
        public DifferenceType differenceType
        {
            get 
            {
                DifferenceType enmType = (DifferenceType)this.typeId;
                return enmType;
            }
            set { this.typeId = (int)value; }

        }

        [DataMember]
        public DifferenceLevel differenceLevel
        {
            get 
            {
                DifferenceLevel enmLevel = (DifferenceLevel)this.levelId;
                return enmLevel;
            }
            set { this.levelId = (short)value; }
        }

    }
}

ClientDifferenceRulesCollection如下所示:

    using System;
using System.Text;
using System.Collections.Generic;
using Momentum.Common.Framework;
using System.Runtime.Serialization;

namespace XYZ.RC.BusinessEntities.Settings
{
    [Serializable]
    [CollectionDataContract(Name = "ClientDifferenceRulesCollection", Namespace = Constants.Namespace)]
    [TypedCollection(typeof(ClientDifferenceRules))]
    [KnownType(typeof(ClientDifferenceRulesCollection))]
    public class ClientDifferenceRulesCollection : BusinessCollectionBase<ClientDifferenceRules>
    {
        public ClientDifferenceRulesCollection() : base(){}    
        public ClientDifferenceRulesCollection(UserSession Session) : base(Session){}    
        public ClientDifferenceRulesCollection(IList<ClientDifferenceRules> initialList)  : base(initialList) { }
    }
}

PropertyEntity看起来像这样(来自元数据):

    [DataContract(Name = "PropertyEntity", Namespace = "http://www.momentum.se//common")]
public class PropertyEntity
{
    public PropertyEntity();
    public PropertyEntity(string name, object value);

    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public object Tag { get; set; }
    public TypeCode typeCode { get; set; }
    [DataMember]
    public TypeOfProperty TypeOfProperty { get; set; }
    [DataMember]
    public object Value { get; set; }
}

1 个答案:

答案 0 :(得分:0)

我放弃了尝试在反序列化时用未知类型解决这个问题,而是重新设计了应用程序。似乎只有太多级别的自己设计的实体和集合才能处理序列化/反序列化机制。

现在我通过一个单独的WCF服务在集合中获取X类型的实体,它就像魅力一样。

非常感谢您的努力!