3

I'm struggeling with a deserialization problem that I haven't found an answer for. The scenario is like this:

A silverlight client signs in to the server and gets a session object back. The session object contains various information, amongst other a collection called UserSettings. The collection contains a type called propertyentity which basically has two properties, a string and an object. When deserializing I get the following error:

System.Runtime.Serialization.SerializationException: JSON contains a '__type' member specifying the data contract name 'http://www.xyz.se/rc:ClientDifferenceRules'. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'ClientDifferenceRules' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer. You can also often eliminate this error by avoiding the use of derived types where the JSON is produced.

When sending other propretyentities in session.UserSettings containing for example ordinary int as the deserialization works perfectly. How can I tell the deserializer what data type it is?

ClientDifferenceRules looks like this:

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 looks like this:

    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 looks like this (from metadata):

    [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; }
}
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Clas
  • 57
  • 4
  • Knowntypes usually go on base classes (or collections thereof) which are serialized polymorphically. You might need to add [KnownType(typeof(ClientDifferenceRules))] to RCBusinessBase and / or any collection of . You can also add known types in web config, and it seems declaratively to your service contracts - http://stackoverflow.com/questions/771560/how-do-you-configure-wcf-known-types-programmatically – StuartLC Dec 16 '11 at 09:18
  • Hi, sorry for the delay but I got stuck with other projects. Now I have tried with adding knowntype(typeof(ClientDifferenceRules)) and knowntype("staticmethodforresolving") to RCBusinessBase but none have solved my problem. I still get the deserialization error that I posted above. I'm stuck! – Clas Jan 04 '12 at 09:01

1 Answers1

0

I gave up trying to solve this problem with unknown types at deserialization and redesigned the application instead. It seemed like it was just too many levels of own designed entities and collections for the serialization/deserialization-mechanism to handle.

Now I'm fetching my entities of type X in a collection via a separate WCF-service and it works like a charm.

Thanks anyway for your efforts!

Clas
  • 57
  • 4