Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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# 如何使用字符串数组值(反)序列化可序列化字典?_C#_.net_Dictionary_Xml Serialization - Fatal编程技术网

C# 如何使用字符串数组值(反)序列化可序列化字典?

C# 如何使用字符串数组值(反)序列化可序列化字典?,c#,.net,dictionary,xml-serialization,C#,.net,Dictionary,Xml Serialization,我需要将C#(.NET Framework 4.5.2)中的一个类与XML进行(反)序列化,该类的字典属性具有string键和string[]数组值。我正在使用另一个问题中提到的SerializableDictionary实现,这意味着我的属性属于SerializableDictionary类型 将其序列化为XML文件看起来效果不错;但是,反序列化总是会因System.InvalidOperationException而失败 即使仅对字典本身进行反序列化,也会发生这种情况。请参阅下面的MSTes

我需要将C#(.NET Framework 4.5.2)中的一个类与XML进行(反)序列化,该类的字典属性具有
string
键和
string[]
数组值。我正在使用另一个问题中提到的
SerializableDictionary
实现,这意味着我的属性属于
SerializableDictionary
类型

将其序列化为XML文件看起来效果不错;但是,反序列化总是会因System.InvalidOperationException而失败

即使仅对字典本身进行反序列化,也会发生这种情况。请参阅下面的MSTest单元测试,它再现了问题:

使用系统;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用My.Namespace.Collections;//其中定义了SerializableDictionary。
使用System.Xml.Serialization;
使用System.IO;
使用System.Linq;
命名空间My.namespace.Collections.Tests
{
/// 
///提供类的单元测试方法。
/// 
[测试类]
公共类SerializableDictionaryTests
{
/// 
///班级进行的基本测试
///(反)序列化。
/// 
[测试方法]
[超时(100)]
public void SerializableDictionary_BasicTest()
{
//安排。
var sourceDictionary=new SerializableDictionary();
可序列化的字典目的字典;
var serializer=新的XmlSerializer(typeof(SerializableDictionary));
var list1=新字符串[]{“苹果”、“香蕉”、“梨”};
var list2=新字符串[]{“胡萝卜”、“花椰菜”、“花椰菜”、“洋葱”};
var list3=新字符串[]{“牛肉”、“鸡肉”};
添加(“水果”,列表1);
添加(“蔬菜”,列表2);
添加(“肉类”,列表3);
//表演。
使用(var stream=new MemoryStream())
{
serializer.Serialize(流,sourceDictionary);
流位置=0;
destinationDictionary=(SerializableDictionary)序列化程序。反序列化(流);
}
//断言。
//注意:我们没有走到这一步,因为它在上面using块中的最后一条语句中崩溃。
AreEqual(3,destinationDictionary.Keys.Count);
Assert.IsTrue(destinationDictionary.ContainsKey(“果实”);
Assert.IsTrue(destinationDictionary.ContainsKey(“蔬菜”);
Assert.IsTrue(destinationDictionary.ContainsKey(“肉类”);
断言.AreEqual(3,destinationDictionary[“果实”]长度);
Assert.IsTrue(destinationDictionary[“水果”]。包含(“苹果”);
Assert.IsTrue(destinationDictionary[“水果”]。包含(“香蕉”);
Assert.IsTrue(destinationDictionary[“水果”]。包含(“梨”);
断言.AreEqual(4,destinationDictionary[“蔬菜”]长度);
Assert.IsTrue(destinationDictionary[“蔬菜”]。包含(“胡萝卜”);
Assert.IsTrue(destinationDictionary[“蔬菜”]。包含(“花椰菜”);
Assert.IsTrue(destinationDictionary[“蔬菜”]。包含(“花椰菜”);
Assert.IsTrue(destinationDictionary[“蔬菜”]。包含(“洋葱”);
断言.AreEqual(2,destinationDictionary[“meats”]长度);
Assert.IsTrue(destinationDictionary[“肉类”]。包含(“牛肉”);
Assert.IsTrue(destinationDictionary[“肉类”]。包含(“鸡肉”);
}
}
}
异常位于
序列化程序。反序列化
调用,并读取:

Test method My.Namespace.Collections.Tests.SerializableDictionaryTests.SerializableDictionary_BasicTest threw exception: 
System.InvalidOperationException: There is an error in XML document (8, 8). ---> System.InvalidOperationException: There is an error in XML document (8, 8). ---> System.InvalidOperationException: <ArrayOfString xmlns=''> was not expected.
编辑#2:


在一些额外的测试之后,将测试中的
SerializableDictionary
声明的
TValue
类型更改为不同的内容,并检查它是否工作,如果
TValue
string
,我可以确认它工作正常,但是如果设置为,我的自定义可序列化类,即使该类用
SerializableAttribute
修饰或实现
IXmlSerializable
接口。因此,这个问题实际上比仅仅使用字符串数组更大。

经过几天的努力,我得出结论,我使用的可序列化的
实现不能用于处理数组和其他对象


我求助于在类上实现
IXmlSerializable
接口,在
WriteXml
方法中将字典值序列化为列表。在
ReadXml
中,我只需对存储的列表进行反序列化,并将其值放回字典中,同时检查列表项上是否没有作为附加属性存储的重复键。它很笨重,但很有效。

我很高兴您找到了解决方案,并成功地使其工作。不确定您是否仍然对解决方案持开放态度。尽管如此,以下是你可以做的事情,让你按照原样生活在
Dictionary

尽管.NET的
XmlSerializer
不支持字典,但有一些libs可以为您做到这一点。其中一个库是SharpSerializer(,),它将任何类型序列化为二进制或XML

使用非常简单:

var serializer = new SharpSerializer(); 
serializer.Serialize(dict, "test.xml");
输入

var dict = new Dictionary<string, string[]> 
{
    { "nikhil", new string[] { "nikhil.0@so.com", "nikhil.1@so.com" } } 
};
<Dictionary name="Root" type="System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <Items>
    <Item>
      <Simple value="nikhil" />
      <SingleArray>
        <Items>
          <Simple value="nikhil.0@so.com" />
          <Simple value="nikhil.1@so.com" />
        </Items>
      </SingleArray>
    </Item>
  </Items>
</Dictionary>
var dict=新字典
{
{“nikhil”,新字符串[]{“nikhil”。0@so.com“尼希尔。1@so.com" } } 
};
输出

var dict = new Dictionary<string, string[]> 
{
    { "nikhil", new string[] { "nikhil.0@so.com", "nikhil.1@so.com" } } 
};
<Dictionary name="Root" type="System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <Items>
    <Item>
      <Simple value="nikhil" />
      <SingleArray>
        <Items>
          <Simple value="nikhil.0@so.com" />
          <Simple value="nikhil.1@so.com" />
        </Items>
      </SingleArray>
    </Item>
  </Items>
</Dictionary>


你考虑了这个答案吗?你能显示结果XML吗?@菲尔多,我认为这是最后一招。这实际上只是一个被序列化的更大的复合对象的一小部分,使用数据协定属性来修饰我的所有子类和属性可能需要一段时间