3

正如标题所说,当我反序列化以下文件时,我只得到第一个(并且总是第一个)元素:

<?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>

我的反序列化代码:

var list = (ServerConnections)mSerializer.Deserialize(inputStream)).Entries;

然后 list.Count 是 1。 ServerConnections 看起来像这样:

public class ServerConnections
{
    public ServerConnectionEntry[] Entries { get; set; }
}

没有例外发生。

编辑: 当我包含执行自定义 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());
}

虽然数据在 ReadXml 之后包含正确的数据,但运行整个列表的反序列化器会停止并且不会读取任何其他元素。

4

3 回答 3

1

我没有看到任何问题。我什至已经复制了您的代码场景(下面附上完整的测试),并且它正在正确地完成它的工作。

尝试在其他地方搜索(例如,确保通过xml的是您所期望的)。但是序列化与您的 C# 类映射一起正常工作

编辑: AuthHash 类不会为您进行往返byte[]转换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);
    }
}
于 2013-06-22T10:50:39.740 回答
1

同样在这里,这似乎对我使用类似于您的代码的我来说很好。

 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; }
    }
}
于 2013-06-22T11:01:13.790 回答
0

好吧 fizzlesticks,问题是我在反序列化中忘记了一小行。它应该是这样的:

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();
}

ReadEndElement 确保它前进到下一个节点。因为我没有这样做,所以上面的反序列化器有问题,但它没有抛出异常,而是停止解析并返回到目前为止得到的结果......

于 2013-06-22T12:24:45.177 回答