简体   繁体   中英

Xmlserializer not serializing base class members

I'm having this very odd issue while trying to serialize a class for logging using XmlSerializer. The code was generated by the wsdl.exe tool. The class that gets serialized as is declared as follows:

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "xxxxx")]
public partial class InheritedRequestA : BaseRequest
{
}

The serialization of other classes that also inherit from BaseRequest includes all non-inherited members, but none of the public members from BaseRequest. BaseRequest is declared as follows.

[System.Xml.Serialization.XmlIncludeAttribute(typeof(InheritedRequestA))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(InheritedRequestB))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "xxxxx")]
public partial class BaseRequest
{
//members here
}

In order to serialize the requests and responses together, I wrote a very basic Wrapper class that just contains a request object and a response object. The code for serialization:

        XmlSerializer serializer = new XmlSerializer(typeof(Wrapper));
        string serializedObject = string.Empty;
        using (MemoryStream stream = new MemoryStream())
        {
            serializer.Serialize(stream, wrapper);
            stream.Position = 0;
            using (StreamReader reader = new StreamReader(stream))
            {
                serializedObject = reader.ReadToEnd();
            }
        }

Any thoughts as to why the public properties inherited from the base class are not getting serialized would be greatly appreciated.

EDIT: Here is the wrapper class. I have subclassed it into ActivatorWrapper and VersionRetrieverWrapper.

[Serializable]
[XmlInclude(typeof(Wrapper))]
[XmlInclude(typeof(ActivatorWrapper))]
[XmlInclude(typeof(VersionRetrieverWrapper))]
public class Wrapper
{
}

[Serializable]
public class VersionRetrieverWrapper : Wrapper
{
    public InheritedRequestA Request { get; set; }
    public InheritedResponseA Response { get; set; }
}

You need to make sure the public members of BaseRequest have values assigned to them (whether in a default constructor, in their declarations, or in your service's code). If not, the XmlSerializer is going to ignore them unless they are both nullable ( int? bool? ) and have the XML IsNullable attribute set to true ( [XmlElement(IsNullable = true)] ).

This is working fine provided that Request/Response are not null. Here is a working sample app:

class Program
{
    static void Main(string[] args)
    {
        var wrapper = new VersionRetrieverWrapper();
        wrapper.Request = new InheritedRequestA();
        wrapper.Request.Member = "Request";
        wrapper.Response = new InheritedResponseA();
        wrapper.Response.Member = "Response";

        Console.WriteLine(Save(wrapper));
    }

    public static string Save(Wrapper wrapper)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Wrapper));

        string serializedObject = string.Empty;
        using (MemoryStream stream = new MemoryStream())
        {
            serializer.Serialize(stream, wrapper);
            stream.Position = 0;
            using (StreamReader reader = new StreamReader(stream))
            {
                serializedObject = reader.ReadToEnd();
            }
        }
        return serializedObject;
    }
}
public partial class InheritedRequestA : BaseRequest
{
}

public partial class InheritedResponseA : BaseRequest
{
}
public partial class BaseRequest
{
    //members here
    public string Member;
}

[XmlInclude(typeof(VersionRetrieverWrapper))]
public class Wrapper
{
}

public class VersionRetrieverWrapper : Wrapper
{
    public InheritedRequestA Request { get; set; }
    public InheritedResponseA Response { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM