views:

693

answers:

2

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; }
}
+1  A: 

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)]).

Nate
A: 

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; }
}
csharptest.net