C# 数组反序列化仅返回1个元素
正如标题所述,当我反序列化以下文件时,我只获得第一个(并且始终是第一个)元素: 和列表。然后计数为1。服务器连接如下所示:C# 数组反序列化仅返回1个元素,c#,.net,xml,C#,.net,Xml,正如标题所述,当我反序列化以下文件时,我只获得第一个(并且始终是第一个)元素: 和列表。然后计数为1。服务器连接如下所示: public class ServerConnections { public ServerConnectionEntry[] Entries { get; set; } } void BigNumber::ReadXml(System::Xml::XmlReader^ reader) { reader->ReadStartElement();
public class ServerConnections
{
public ServerConnectionEntry[] Entries { get; set; }
}
void BigNumber::ReadXml(System::Xml::XmlReader^ reader) {
reader->ReadStartElement();
XmlSerializer^ serializer = gcnew XmlSerializer(cli::array<Byte>::typeid);
cli::array<Byte>^ data = (cli::array<Byte>^)serializer->Deserialize(reader);
pin_ptr<unsigned char> ptr(&data[0]);
BN_bin2bn(ptr, data->Length, mNumber);
reader->ReadEndElement();
}
没有例外
编辑:
当我包含执行自定义xml序列化(实现IXmlSerializable)的类时,就会出现问题。它的作用如下:
void BigNumber::ReadXml(System::Xml::XmlReader^ reader) {
reader->ReadStartElement();
XmlSerializer^ serializer = gcnew XmlSerializer(cli::array<Byte>::typeid);
cli::array<Byte>^ data = (cli::array<Byte>^)serializer->Deserialize(reader);
pin_ptr<unsigned char> ptr(&data[0]);
BN_bin2bn(ptr, data->Length, mNumber);
}
void BigNumber::WriteXml(System::Xml::XmlWriter^ writer) {
XmlSerializer^ serializer = gcnew XmlSerializer(cli::array<Byte>::typeid);
serializer->Serialize(writer, ToByteArray());
}
void BigNumber::ReadXml(System::Xml::XmlReader^reader){
reader->ReadStartElement();
XmlSerializer^serializer=gcnew XmlSerializer(cli::array::typeid);
cli::array^ data=(cli::array^)序列化程序->反序列化(读取器);
pin_ptr ptr(&data[0]);
BN_bin2bn(ptr,数据->长度,mNumber);
}
void BigNumber::WriteXml(系统::Xml::XmlWriter^writer){
XmlSerializer^serializer=gcnew XmlSerializer(cli::array::typeid);
序列化程序->序列化(编写器,ToByteArray());
}
虽然读取XML后数据包含正确的数据,但运行整个列表的反序列化程序将停止,并且不会读取任何其他元素。我看不出任何问题。我甚至复制了您的代码场景(下面附上了完整的测试),它正确地完成了它的工作 尝试在其他地方搜索(例如,确保传递的
xml
是您期望的内容)。但是序列化在C#类映射中工作正常
编辑:AuthHash类否为您执行从字节[]
到base64
的转换
public class ServerConnections
{
public ServerConnectionEntry[] Entries { get; set; }
}
public class ServerConnectionEntry
{
public string Name { get; set; }
public AuthHash AuthHash { get; set; }
}
public class AuthHash
{
[XmlIgnore]
public byte[] Hash { get; set; }
public string base64Binary
{
get { return Convert.ToBase64String(Hash); }
set { Hash = Convert.FromBase64String(value); }
}
}
[TestClass]
public class DeserializationTest
{
public const string MyXml = @"<?xml version=""1.0""?>
<ServerConnections
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<Entries>
<ServerConnectionEntry>
<Name>Local</Name>
<Host>127.0.0.1</Host>
<Port>15556</Port>
<Username>TestUser</Username>
<AuthHash>
<base64Binary>u7a0NN4uOvCrb5t5UWVVEl14Ygo=</base64Binary>
</AuthHash>
</ServerConnectionEntry>
<ServerConnectionEntry>
<Name>Local2</Name>
<Host>127.0.0.1</Host>
<Port>15556</Port>
<Username>TestUser</Username>
<AuthHash>
<base64Binary>u7a0NN4uOvCrb5t5UWVVEl14Ygo=</base64Binary>
</AuthHash>
</ServerConnectionEntry>
</Entries>
</ServerConnections>
";
[TestMethod]
public void Deserialization_Has_Two_Elements()
{
TextReader reader = new StringReader(MyXml);
var mySerializer = new XmlSerializer(typeof(ServerConnections));
var list = ((ServerConnections)mySerializer.Deserialize(reader)).Entries;
Assert.IsTrue(list.Count() == 2);
Assert.IsTrue(list.First().Name == "Local");
Assert.IsTrue(list.Last().Name == "Local2");
Assert.IsTrue(list.First().AuthHash.Hash.Length > 0);
Assert.IsTrue(list.Last().AuthHash.Hash.Length > 0);
}
}
公共类服务器连接
{
public ServerConnectionEntry[]条目{get;set;}
}
公共类ServerConnectionEntry
{
公共字符串名称{get;set;}
公共AuthHash AuthHash{get;set;}
}
公共类AuthHash
{
[XmlIgnore]
公共字节[]散列{get;set;}
基于二进制的公共字符串
{
获取{return Convert.ToBase64String(Hash);}
set{Hash=Convert.FromBase64String(值);}
}
}
[测试类]
公共类反序列化测试
{
公共常量字符串MyXml=@”
地方的
127.0.0.1
15556
测试用户
U7A0NN4UOVCRB5T5UHVVEL14YGO=
本地2
127.0.0.1
15556
测试用户
U7A0NN4UOVCRB5T5UHVVEL14YGO=
";
[测试方法]
public void反序列化\u有两个\u元素()
{
TextReader=新的StringReader(MyXml);
var mySerializer=新的XmlSerializer(typeof(ServerConnections));
var list=((服务器连接)mySerializer.Deserialize(reader)).Entries;
Assert.IsTrue(list.Count()==2);
Assert.IsTrue(list.First().Name==“Local”);
Assert.IsTrue(list.Last().Name==“Local2”);
Assert.IsTrue(list.First().AuthHash.Hash.Length>0);
Assert.IsTrue(list.Last().AuthHash.Hash.Length>0);
}
}
这里也一样,使用类似于您的代码对我来说似乎很好
public class Program
{
static void Main(string[] args)
{
XmlSerializer deserializer = new XmlSerializer(typeof(ServerConnections));
var reader = new StreamReader(@"../../Test.xml");
var entries = (ServerConnections)deserializer.Deserialize(reader);
reader.Close();
}
public class ServerConnections
{
public ServerConnectionEntry[] Entries { get; set; }
}
public class ServerConnectionEntry
{
public string Name { get; set; }
public string Host { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public BinaryCode AuthHash { get; set; }
}
public class BinaryCode
{
[XmlElement("base64Binary")]
public string Code { get; set; }
}
}
好吧,问题是我忘记了反序列化中的一小行。应该是这样的:
public class ServerConnections
{
public ServerConnectionEntry[] Entries { get; set; }
}
void BigNumber::ReadXml(System::Xml::XmlReader^ reader) {
reader->ReadStartElement();
XmlSerializer^ serializer = gcnew XmlSerializer(cli::array<Byte>::typeid);
cli::array<Byte>^ data = (cli::array<Byte>^)serializer->Deserialize(reader);
pin_ptr<unsigned char> ptr(&data[0]);
BN_bin2bn(ptr, data->Length, mNumber);
reader->ReadEndElement();
}
void BigNumber::ReadXml(System::Xml::XmlReader^reader){
reader->ReadStartElement();
XmlSerializer^serializer=gcnew XmlSerializer(cli::array::typeid);
cli::array^ data=(cli::array^)序列化程序->反序列化(读取器);
pin_ptr ptr(&data[0]);
BN_bin2bn(ptr,数据->长度,mNumber);
reader->ReadEndElement();
}
ReadEndElement确保它前进到下一个节点。由于我没有这样做,上面的反序列化程序出现了问题,但它没有抛出异常,而是停止解析并返回到目前为止得到的结果…我实际上发现问题在于我对BigNumber AuthHash的反序列化。它显然会跳到下一个元素,因此只读取其中一个元素。不过,xml序列化程序似乎工作正常。如果您尝试一下,AuthHash元素的反序列化可以很好地处理上述内容(更改两个AuthHash元素中每个元素的字符串以使其更容易)。我想您可以尝试使用托管类进行读取&然后映射到非托管类,因为我不知道在本例中使用非托管类的后果。这确实会使到已定义类型的映射有点脏,尽管您是对的,但这与反序列化本身无关,而是在im下面使用非托管类(AuthHash),这似乎会导致问题。如果我从xml中删除AuthHash,它将读取所有元素。我已经演示了如何将base64转换为byte[]并返回。。。这应该可以解决所有问题,但在我的例子中,AuthHash是一个包装非托管对象的C++/CLI类。因此,当序列化/反序列化时,它需要特殊的“处理”。