使用C#XmlSerializer对数组元素进行额外包装
我有以下课程:使用C#XmlSerializer对数组元素进行额外包装,c#,arrays,xml,serialization,C#,Arrays,Xml,Serialization,我有以下课程: namespace XmlSerializerTest { using System; using System.Collections.Generic; using System.Xml.Serialization; [Serializable] [XmlRoot( Namespace = "My:NS" )] [XmlType( Namespace = "My:NS" )] [XmlInclude( typeof( C
namespace XmlSerializerTest
{
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
[Serializable]
[XmlRoot( Namespace = "My:NS" )]
[XmlType( Namespace = "My:NS" )]
[XmlInclude( typeof( Command ) )]
[XmlInclude( typeof( ImSession ) )]
public class CommandBase
{
[XmlAttribute]
public string Version { get; set; }
}
[Serializable]
[XmlType( Namespace = "My:NS" )]
[XmlInclude( typeof( ImSession[ ] ) )]
public class Command : CommandBase
{
[XmlArray]
[XmlArrayItem( typeof( ImSession ) )]
public object[ ] Content { get; set; }
}
[Serializable]
[XmlType( Namespace = "My:NS" )]
public class ImSession
{
[XmlElement]
public string ClientId { get; set; }
[XmlElement]
public DateTime StartTime { get; set; }
[XmlArray]
public List<Matrix.Xmpp.Client.Message> Messages { get; set; }
}
}
这将导致以下XML,同一序列化程序无法正确反序列化:
<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">
<Content>
<ImSession>
<ClientId>Client A</ClientId>
<StartTime>2015-08-11T00:00:00-04:00</StartTime>
<Messages>
<Message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY A</body>
</message>
</Message>
<Message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY B</body>
</message>
</Message>
</Messages>
</ImSession>
<ImSession>
<ClientId>Client B</ClientId>
<StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
<Messages>
<Message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY C</body>
</message>
</Message>
<Message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY D</body>
</message>
</Message>
</Messages>
</ImSession>
</Content>
</CommandBase>
在调试器中检查
d
,可以发现它实际上是一个命令对象,其中包含ImSessions,每个消息的Messages数组中都有对象,它声称是Matrix.Xmpp.Client.Message,但除了子节点的私有集合外,所有属性都为null(与xml匹配),其中包含实际的消息对象,所有属性与预期一致。嵌套似乎来自矩阵.Xmpp.Client.Message
类本身。您是否尝试过序列化和反序列化该类的单个实例?似乎不是开源的,所以你能用一个简单的替换类重现这个问题吗?是的。(小写)元素来自矩阵。该类继承自XElement,并对其调用ToString将生成与上面xml中显示的完全相同的元素。我更感兴趣的是额外(大写m)元素来自何处,以及为什么运行时无法反序列化它序列化的内容,即使在同一应用程序中使用相同的XMLSerializer。它不应该是1对1吗?默认情况下,XmlSerializer
将集合包装在容器元素中。如果你不想要这个,请参阅。然而,我不认为这是你问题的原因。当我试图用一个简单的POCO代替Matrix.Xmpp.Client.Message
来重现您的问题时,我做不到(反序列化工作很好)。所以我认为消息
有问题。但是,为了以防万一,请尝试一下这个答案。另外,你能用反序列化代码更新你的问题吗?您只显示序列化。已将反序列化程序代码添加到文章底部。我不担心Messages包装器元素。我希望在整个集合中有一个包装器元素,但在集合中的每个项目周围没有额外的包装器。即使是这样,是否有方法覆盖该行为并将每个元素的序列化留给该对象本身?嵌套似乎来自Matrix.Xmpp.Client.Message
类本身。您是否尝试过序列化和反序列化该类的单个实例?似乎不是开源的,所以你能用一个简单的替换类重现这个问题吗?是的。(小写)元素来自矩阵。该类继承自XElement,并对其调用ToString将生成与上面xml中显示的完全相同的元素。我更感兴趣的是额外(大写m)元素来自何处,以及为什么运行时无法反序列化它序列化的内容,即使在同一应用程序中使用相同的XMLSerializer。它不应该是1对1吗?默认情况下,XmlSerializer
将集合包装在容器元素中。如果你不想要这个,请参阅。然而,我不认为这是你问题的原因。当我试图用一个简单的POCO代替Matrix.Xmpp.Client.Message
来重现您的问题时,我做不到(反序列化工作很好)。所以我认为消息
有问题。但是,为了以防万一,请尝试一下这个答案。另外,你能用反序列化代码更新你的问题吗?您只显示序列化。已将反序列化程序代码添加到文章底部。我不担心Messages包装器元素。我希望在整个集合中有一个包装器元素,但在集合中的每个项目周围没有额外的包装器。即使是这样,是否有方法覆盖该行为并将每个元素的序列化留给该对象本身?
<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">
<Content>
<ImSession>
<ClientId>Client A</ClientId>
<StartTime>2015-08-11T00:00:00-04:00</StartTime>
<Messages>
<Message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY A</body>
</message>
</Message>
<Message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY B</body>
</message>
</Message>
</Messages>
</ImSession>
<ImSession>
<ClientId>Client B</ClientId>
<StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
<Messages>
<Message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY C</body>
</message>
</Message>
<Message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY D</body>
</message>
</Message>
</Messages>
</ImSession>
</Content>
</CommandBase>
<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">
<Content>
<ImSession>
<ClientId>Client A</ClientId>
<StartTime>2015-08-11T00:00:00-04:00</StartTime>
<Messages>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY A</body>
</message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY B</body>
</message>
</Messages>
</ImSession>
<ImSession>
<ClientId>Client B</ClientId>
<StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
<Messages>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY C</body>
</message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY D</body>
</message>
</Messages>
</ImSession>
</Content>
</CommandBase>
StringBuilder sb = new StringBuilder( );
ser.Serialize( new StringWriter( sb ), c );
object d = ser.Deserialize( new StringReader( sb.ToString( ) ) );