代码之家  ›  专栏  ›  技术社区  ›  V0ldek

XmlSerializer不反序列化列表<string>

  •  0
  • V0ldek  · 技术社区  · 7 年前

    我试图序列化和反序列化的类(大致上):

    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>
    

    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>

    2 回复  |  直到 7 年前
        1
  •  0
  •   Parrish Husband    7 年前

    试试这个:

    [XmlRoot]
    public class MyDto
    {
        [XMLElement]
        public string Name { get; set; }
    
        [XmlArray("UniqueNames"), XmlArrayItem("UniqueName")]
        public List<string> UniqueNameStrings { get; set; }
    
        public MyDto() { }
    }
    

    试一试这个序列化程序:

    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;
            }
        }
    }
    
        2
  •  0
  •   Bouke    7 年前

    例子:

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

    使用配置名称

    推荐文章