none
Problems with deserilization of generic types using the DataContractSerializer RRS feed

  • Question

  • Hello

    I'm using the DataContractSerializer the first time.

    I'm passing the KnownTypes to the DataContractSerializer in its constructor as a List of Types:

                DataContractSerializer dataContractSerializer;
                var knownTypes = new List<Type>() 
                    {   
                        typeof(AnyClass),
                        typeof(AnyOtherClass)
                    };
                dataContractSerializer = new DataContractSerializer(typeof(Expression), knownTypes, int.MaxValue, true, true, null);

    Now the problem is that I'm not able to pass a generic type here because typeof(AnyGenericClass<T>) does not work, the type must be defined at compile time.

    My generic class, lets call it AnyGenericClass<T> uses different enums of other classes which all have the same names so i just tryed to add all of them to KnownTypes

    DataContractSerializer dataContractSerializer; var knownTypes = new List<Type>() { typeof(AnyClass), typeof(AnyOtherClass),
    typeof(AnyGenericClass<AnyClass.MyEnum>),
    typeof(AnyGenericClass<AnyOtherClass.MyEnum>), }; dataContractSerializer = new DataContractSerializer(typeof(Expression), knownTypes, int.MaxValue, true, true, null);


    That compiled well but did not work, the serializer told me i should remove all of them except of one which also did not work because now it threw the old Exception which said he does not know the types.

    I Realized there must be another way so I read this:

    http://msdn.microsoft.com/en-us/library/ms730167.aspx

    In the part "Known Types Using Open Generic Method" I found a solution

        private static Type[] GetKnownType()
        {
            return new Type[] { typeof(MyGenericType<T>) };
        }

    It worked well and I could now serialize my objects.

    I was presented some XML like that:

    <AnyParent xmlns:a="http://schemas.datacontract.org/2004/07/AnyGenericClass">
      <a:AnyGenericClass anyattr="123" i:type="a:AnyGenericClass" />
      <a:AnyGenericClass anyattr="345" i:type="a:AnyGenericClass" />
      <a:AnyGenericClass anyattr="678" i:type="a:AnyGenericClass" />
    </AnyParent>
    		

    Now deserialization does not work, the Exception Message says something like:

    Error in line x position y. The element http://...../07/AnyGenericClass contains Data of a type that is mapped with the name http://...../07/AnyGenericClass. The deserializer does not know any type that is mapped with that name.

    And so on and so on.

    I already tryed to use a DataContractResolver but how should that work? There is no chance to define the correct type with the data from the XML.

    • Moved by John SaundersModerator Monday, October 22, 2012 8:10 PM wcf q (From:ASMX Web Services and XML Serialization)
    Thursday, October 18, 2012 7:05 AM

All replies

  • Please check if you have specify type of the object for the deserialization. Try specify your known type as below

    [DataContract]  
    [KnownType(typeof(Student))]
    public abstract class StudentBase:IStudent
    {
    //add your content here
    }
    

    Tuesday, October 23, 2012 7:20 AM
  • Hi, thank you for your respons.

    I defined all the types of that my AnyClass<T> can be. The Types are Enums of subclasses which all have the same name.

    so i have got something like that:


    public class AnyBaseClass {...}
    
    public class FristSubClass : AnyBaseClass {
      public enum AnyEnum {
        x,
        y
      }
    }
    
    public class SecondSubClass : AnyBaseClass {
      public enum AnyEnum {
        z,
        abc
      }
    }
    
    public class ThirdSubClass : AnyBaseClass {
      public enum AnyEnum {
        e,
        f,
        g
      }
    }
    
    public class AnyClass<T> {...}


    And the Type of AnyClass<T> is always AnyEnum.

    Like that: AnyClass<FristSubClass.AnyEnum>

    So what i did is adding all the Enums to the known type list:

               var knownTypes = new List<Type>() 
                    {   
                        typeof(FirstClass),
                        typeof(FirstClass.AnyEnum),
                        typeof(SecondClass),
                        typeof(SecondClass.AnyEnum),
                        typeof(ThirdClass),
                        typeof(ThirdClass.AnyEnum)
                    };
               dataContractSerializer = new DataContractSerializer(typeof(Expression), knownTypes, int.MaxValue, true, true, null);

    But it did not work, i finally had to remove the Generic Class and redesign my program a little bit which made a few things not so nice as they where before.

    • Edited by Toterbiber Friday, October 26, 2012 1:05 PM
    Friday, October 26, 2012 1:02 PM