Как десериализовать типы не известно, не обычный случай - PullRequest
3 голосов
/ 16 декабря 2011

Я борюсь с проблемой десериализации, для которой я не нашел ответа.Сценарий выглядит следующим образом:

Клиент Silverlight входит на сервер и возвращает объект сеанса обратно.Объект сеанса содержит различную информацию, в том числе коллекцию, называемую UserSettings.Коллекция содержит тип, называемый propertyentity, который в основном имеет два свойства: строку и объект.При десериализации я получаю следующую ошибку:

System.Runtime.Serialization.SerializationException: JSON содержит член '__type', указывающий имя контракта данных 'http://www.xyz.se/rc:ClientDifferenceRules'. Десериализатор не знает ни о каком типе, которыйкарты к этому контракту.Добавьте тип, соответствующий «ClientDifferenceRules», в список известных типов - например, с помощью атрибута KnownTypeAttribute или добавив его в список известных типов, передаваемых в DataContractSerializer.Вы также можете часто устранить эту ошибку, избегая использования производных типов, в которых создается JSON.

При отправке других свойств в session.UserSettings, содержащих, например, обычный 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 голосов
/ 05 января 2012

Я отказался от попыток решить эту проблему с неизвестными типами при десериализации и изменил дизайн приложения.Казалось, что слишком много уровней собственных разработанных сущностей и коллекций для механизма сериализации / десериализации.

Теперь я выбираю свои сущности типа X в коллекции через отдельный WCF-сервиси это работает как шарм.

В любом случае, спасибо за ваши усилия!

...