我正在尝试序列化和反序列化的类(大致):
class MyDto
{
public string Name { get; set; }
private List<string> _uniqueNameStrings = new List<string>();
[XmlArray("UniqueNames")]
[XmlArrayItem("string")]
public List<string> UniqueNameStrings
{
get => _uniqueNameStrings;
set => _uniqueNameStrings = value ?? new List<string>();
}
}
没有进行null
检查的先前版本,也不起作用:
class MyDto
{
public string Name { get; set; }
[XmlArray("UniqueNames")]
[XmlArrayItem("string")]
public List<string> UniqueNameStrings { get; set; }
}
为此类生成的模式:
<xs:complexType name="MyDto">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Name" nillable="true" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="UniqueNames" type="ArrayOfString" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArrayOfString">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
以及序列化的效果:
<MyDto>
<Name>MyDtoName</Name>
<UniqueNames>
<string>SomeName</string>
<string>SomeOtherName</string>
<!-- ... <-->
</UniqueNames>
</MyDto>
因此序列化看起来可以正常工作,问题是在反序列化时,XML似乎完全忽略了字符串值。这是调用代码:
using System.IO.Abstractions;
private IFileSystem _fileSystem;
public void SerializeDto(object dto, string filePath)
{
var serializer = new XmlSerializer(dto.GetType());
using (var streamWriter = _fileSystem.FileStream.Create(filePath, FileMode.Create, FileAccess.Write))
{
serializer.Serialize(streamWriter, dto);
streamWriter.Flush();
}
}
public T DeserializeDto<T>(string filePath) where T : class
{
var serializer = new XmlSerializer(typeof(T));
using (var streamReader = _fileSystem.FileStream.Create(filePath, FileMode.Open, FileAccess.Read))
{
return (T) serializer.Deserialize(streamReader);
}
}
Name
属性(以及为简单起见我省略的所有其他属性)已正确反序列化,而UniqueNames
被保留为空。我在set
方法上设置了一个断点,并且可以看到反序列化器使用value
等效于空的List<string>
来调用它,就像<string>
元素没有存在。由于我无法查看XML代码以查看发生了什么,因此我陷入了困境。关于XmlSerializer为什么忽略字符串数组中的值的任何想法?特别是因为它本身已经将值序列化为这种格式,现在无法处理回读...
答案 0 :(得分:0)
尝试一下:
[XmlRoot]
public class MyDto
{
[XMLElement]
public string Name { get; set; }
[XmlArray("UniqueNames"), XmlArrayItem("UniqueName")]
public List<string> UniqueNameStrings { get; set; }
public MyDto() { }
}
我无法从示例代码中看出来,但它可能是缺少的空类构造函数。我还更新了XmlArrayItem,以为调用它的“字符串”可能会发生冲突。
给这个序列化器一个镜头:
public static void Serialize<T>(T t, string filePath, bool overwrite = true)
{
using (var fs = new FileStream(filePath, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.Write))
{
var serializer = new XmlSerializer(typeof(T));
var ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Omits xmlns:xsi/xmlns:xsd
try
{
serializer.Serialize(fs, t, ns);
}
catch (System.Exception)
{
if (File.Exists(filePath))
File.Delete(filePath);
throw;
}
}
}
答案 1 :(得分:0)
示例:
XML:
<Names>
<Names>John</Names>
<Names>Doe</Names>
<Names>Martin</Names>
<Names>Looter</Names>
</Names>
C#:
public class Configuration
{
[XmlArray("Names")]
[XmlArrayItem("Names")]
public List<string> Names { get; set; }
public Load(Stream stream)
{
var xmlSerializer = new XmlSerializer(typeof(Configuration));
var config = (Configuration)xmlSerializer.Deserialize(stream);
return config;
}
}
使用config.Names