type xxxx not expected use xmlinclude or soapinclude

18,084

Normally, you should add an [XmlInclude] to the ResponseObject class. In this case, it doesn't work because of the SerializableDictionary that you're using. That class creates another XmlSerializer in its implementation, and therefore it doesn't care about your [XmlInclude]'s. Basically it just cannot handle your use case. You should switch from the XmlSerializer to the DataContractSerializer which handles the Dictionary class and supports the [KnownType] attribute to register additional types: http://pastebin.com/vGLSaxHF . Also note that it's pointless to add [DataContract] and [DataMember] attributes in your current case because the XmlSerializer ignores those attributes, they are used by the DataContractSerializer only. Or if you're not sure how to change your serializer (I know I'm not) then you should either not be using a Dictionary or change the SerializableDictionary implementation to handle the dynamic object types that you want to use (find every line where it creates a new XmlSerializer). Or, as an alternative, define a base class for all your objects that you will ever put into the dictionary and do it like this:

[XmlInclude(typeof(Class1), XmlInclude(typeof(Class2)), etc]
public class AbstractBase { }

public class Class1 : AbstractBase { ... }

public class Class2 : AbstractBase { ... }

public class BigClass {
    public SerializableDictionary<string, AbstractBase> Dictionary { get; set; }
}

This way, when the SerializableDictionary creates its own XmlSerializer, it will recognize the AbstractBase and from there, all of its descendants.

Share:
18,084
clicky
Author by

clicky

Updated on June 16, 2022

Comments

  • clicky
    clicky almost 2 years

    I have a curious case of this serialization issue - which has been asked many times on this site and I have gone through a few of these questions and tried the usual items to no avail:

    • Add [XmlInclude] to the class throwing the error
    • Remove namespaces
    • Add a different namespace to each class

    To explain further, I have provided a simplified version of my code below. Essentially I am using a WebServiceHost object to run a RESTful service and one of my endpoints returns an object serialized as XML (I have annotated the object with [DataContract] and [DataMember] attributes). This object contains a SerializableDictionary<string, object> (here) where the value has been typed as object. I believe this is why it is failing:

    • Works fine when the value is assigned a primitive
    • When I assign a custom object to the KV pair V, I get the unexpected type exception probably because the Serializer does not know how to serilaize the object / some sort of namespacing issue

    Obviously, I am unable to annotate Object.cs with [XmlInclude] and because it is a service and I am not myself serializing I cannot using something like

    new Serializer(typeof(...), new Type[] { ... }}
    

    Any idea's of what I can do? I thought about not typing the dict value as object and rtaher comething more concrete but the problem is that this value can take primitives or cusotm types. Some code to explain the above:

    Edit: Updated the code below to make it more clear

    [DataContract]
    public class ResponseObject
    {
        [DataMember(Name = "data")]
        public SerializableDictionary<string, object> Data { get;set; }
    
        public ResponseObject()
        {
            Data = new SerializableDictionary<string, object>();
        }
    }
    
    ...
    
    var d1 = new ResponseObject();
    d1.Data.Add("some key", "some value"); //WORKS AND SERIALIZES PERFECLTY
    
    var d2 = new ResponseObject();
    d2.Data.Add("some other key", new SomeOtherObjecT());
    var d3 = new ResponseObject();
    d3.Data.Add("another key", d2);  //THIS THROWS THE UNEXPECTED TYPE ERROR WHEN SEIRLAIZING SomeOtherObject
    

    Edit: The error is thrown in SerializableDictionary where it is attempting to serialize an object of type ResponseObject. The two are in seperate projects - if that is significant?