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.D开发者_如何学JAVAiagnostics.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; }
}
精彩评论