Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数组反序列化仅返回1个元素_C#_.net_Xml - Fatal编程技术网

C# 数组反序列化仅返回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();

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

和列表。然后计数为1。服务器连接如下所示:

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类。因此,当序列化/反序列化时,它需要特殊的“处理”。