• 序列化与反序列化


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Serialization;
    using System.IO;
    using System.Globalization;
    
    namespace SerializeSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                XmlSerializer serializer = new XmlSerializer(typeof(TemplateDescription[]));
                StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
    
                List<TemplateDescription> list = new List<TemplateDescription>();
                TemplateDescription template = new TemplateDescription("aaa", "bbb", 100);
                template.ObjectValue = new int[2] { 1, 2 };
                TemplateDescription template2 = new TemplateDescription("mmm", "nnn", 101);
                template2.ObjectValue = new byte[2] { 3, 4 };
    
                list.Add(template);
                list.Add(template2);
    
                // Serialize
                serializer.Serialize(writer, list.ToArray());
                File.WriteAllText(@"d:serialize.txt", writer.ToString());
                Console.WriteLine(writer.ToString());
    
                // DeSerialize
                TemplateDescription[] test = (TemplateDescription[])serializer.Deserialize(new StringReader(writer.ToString()));
                Console.WriteLine(test[0].ToString());
            }
        }
    
        [XmlInclude(typeof(int[]))]
        public class TemplateDescription
        {
            public TemplateDescription()
            {
                this.Name = string.Empty;
                this.Description = string.Empty;
                this.ID = 0;
                this.ObjectValue = null;
            }
    
            public TemplateDescription(string name, string description, int id)
            {
                this.Name = name;
                this.Description = description;
                this.ID = id;
            }
    
            public string Name { get; set; }
            public string Description { get; set; }
            public int ID { get; set; }
    
            [XmlElement("Value")]
            public object ObjectValue { get; set; }
    
            [XmlIgnore]
            public int[] IntegerArrayValue
            {
                get { return (int[])ObjectValue; }
                set { ObjectValue = value; }
            }
    
            [XmlIgnore]
            public byte[] ByteArrayValue
            {
                get { return (byte[])ObjectValue; }
                set { ObjectValue = value; }
            }
        }
    
    }
    View Code

    xml format的序列化只是针对公有属性。

    1. 序列化数组,需要指定特质属性[XmlArrayItem(typeof(...))]。

    如果不指定则有可能不能正确序列化,从实验看int数组不指定也可以正确序列化,byte数组就必须得指定。如下:

    public class MyClass
        {
            public int[] IDs { get; set; }
    
            public byte[] BTs { get; set; }
    
            public char Charactor { get; set; }
    
            public MyClass()
            {
                this.IDs = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
                this.BTs = new byte[] { 121, 122, 123, 124, 255, 201 };
                this.Charactor = 'a';
            }
        }

    序列化结果,BTs看上去不正确,其实是经过了based64编码的结果,是正确的。但是如果想得到显式的结果最好加上[XmlArrayItem(typeof(byte))]。

    <?xml version="1.0" encoding="utf-16"?>
    <MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <IDs>
    <int>1</int>
    <int>2</int>
    <int>3</int>
    <int>4</int>
    <int>5</int>
    <int>6</int>
    <int>7</int>
    <int>8</int>
    <int>9</int>
    <int>0</int>
    </IDs>
    <BTs>eXp7fP/J</BTs>
    <Charactor>97</Charactor>
    </MyClass>

    加上特制属性:

        public class MyClass
        {
            public int[] IDs { get; set; }
    
            [XmlArrayItem(typeof(byte))]
            public byte[] BTs { get; set; }
    
            public char Charactor { get; set; }
    
            public MyClass()
            {
                this.IDs = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
                this.BTs = new byte[] { 121, 122, 123, 124, 255, 201 };
                this.Charactor = 'a';
            }
        }
    
    
            static void Test5()
            {
                XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
                StringWriter writer = new StringWriter();
                MyClass myObject = new MyClass();
    
                serializer.Serialize(writer, myObject);
                Console.WriteLine(writer.ToString());
            }

    序列化正确:

    <?xml version="1.0" encoding="utf-16"?>
    <MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <IDs>
        <int>1</int>
        <int>2</int>
        <int>3</int>
        <int>4</int>
        <int>5</int>
        <int>6</int>
        <int>7</int>
        <int>8</int>
        <int>9</int>
        <int>0</int>
      </IDs>
      <BTs>
        <unsignedByte>121</unsignedByte>
        <unsignedByte>122</unsignedByte>
        <unsignedByte>123</unsignedByte>
        <unsignedByte>124</unsignedByte>
        <unsignedByte>255</unsignedByte>
        <unsignedByte>201</unsignedByte>
      </BTs>
      <Charactor>97</Charactor>
    </MyClass>

    2. 当某个需要序列化的field或者property具有不确定的类型时,如果要正确序列化它必须在类型上指定[XmlInclude(typeof(...)),XmlInclude(typeof(...))]属性,标识property可能的类型。

    如下,public object ObjectValue { get; set; }属性可能是int[],byte[], 所以TemplateDescription加XmlInclude属性。

        [XmlInclude(typeof(byte[])), XmlInclude(typeof(int[]))]
        public class TemplateDescription

      Notes:

         只加[XmlInclude(typeof(int[]))]也可以正确序列化byte[]数组的情况。

            [XmlInclude(typeof(int[]))]
            public class TemplateDescription

        只不过 byte[]数组序列化为based64编码结果<Value xsi:type="xsd:base64Binary">AwQ=</Value>,请考虑序加[XmlArrayItem(typeof(byte))] 。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Xml.Serialization;
     6 using System.IO;
     7 using System.Globalization;
     8 
     9 namespace SerializeSample
    10 {
    11     class Program
    12     {
    13         static void Main(string[] args)
    14         {
    15             XmlSerializer serializer = new XmlSerializer(typeof(TemplateDescription[]));
    16             StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
    17 
    18             List<TemplateDescription> list = new List<TemplateDescription>();
    19             TemplateDescription template = new TemplateDescription("aaa", "bbb", 100);
    20             template.ObjectValue = new int[2] { 1, 2 };
    21             TemplateDescription template2 = new TemplateDescription("mmm", "nnn", 101);
    22             template2.ObjectValue = new byte[2] { 3, 4 };
    23 
    24             list.Add(template);
    25             list.Add(template2);
    26 
    27             // Serialize
    28             serializer.Serialize(writer, list.ToArray());
    29             File.WriteAllText(@"d:serialize.txt", writer.ToString());
    30             Console.WriteLine(writer.ToString());
    31 
    32             // DeSerialize
    33             TemplateDescription[] test = (TemplateDescription[])serializer.Deserialize(new StringReader(writer.ToString()));
    34             Console.WriteLine(test[0].ToString());
    35         }
    36     }
    37 
    38     [XmlInclude(typeof(byte[])), XmlInclude(typeof(int[]))]
    39     public class TemplateDescription
    40     {
    41         public TemplateDescription()
    42         {
    43             this.Name = string.Empty;
    44             this.Description = string.Empty;
    45             this.ID = 0;
    46             this.ObjectValue = null;
    47         }
    48 
    49         public TemplateDescription(string name, string description, int id)
    50         {
    51             this.Name = name;
    52             this.Description = description;
    53             this.ID = id;
    54         }
    55 
    56         public string Name { get; set; }
    57         public string Description { get; set; }
    58         public int ID { get; set; }
    59 
    60         [XmlElement("Value")]
    61         public object ObjectValue { get; set; }
    62 
    63         [XmlIgnore]
    64         public int[] IntegerArrayValue
    65         {
    66             get { return (int[])ObjectValue; }
    67             set { ObjectValue = value; }
    68         }
    69 
    70         [XmlIgnore]
    71         public byte[] ByteArrayValue
    72         {
    73             get { return (byte[])ObjectValue; }
    74             set { ObjectValue = value; }
    75         }
    76     }
    77 
    78 }
     1 <?xml version="1.0" encoding="utf-16"?>
     2 <ArrayOfTemplateDescription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     3   <TemplateDescription>
     4     <Name>aaa</Name>
     5     <Description>bbb</Description>
     6     <ID>100</ID>
     7     <Value xsi:type="ArrayOfInt">
     8       <int>1</int>
     9       <int>2</int>
    10     </Value>
    11   </TemplateDescription>
    12   <TemplateDescription>
    13     <Name>mmm</Name>
    14     <Description>nnn</Description>
    15     <ID>101</ID>
    16     <Value xsi:type="xsd:base64Binary">AwQ=</Value>
    17   </TemplateDescription>
    18 </ArrayOfTemplateDescription>

     二.

    注意:当类成员变量中出现不能被序列化的类或接口时候我们要通过

    [NonSerialized]   只针对成员变量

    [XmlIgnore]   针对成员变量和属性,只针对XML序列化

    标记其不被序列化和反序列化

    特别注意:要使某属性在XML序列化过程中不被序列化只能使用[XmlIgnore],[NonSerialized]无效

    三.

     “上午同事问我一个问题,实体序列化时报了一个错:The type ConsoleTest.Item was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically. 分析之后,发现了问题,原来被序列化的实体其中一个Property的类型是Object,但是实例化时给这个Property赋了一个自定义的Item,因此序列化未通过。之后,在Property上加上属性[XmlElement(typeof(Item))]即可序列化成功。
           利用Xml序列化技术进行开发有一段时间了,总结了此应用的一些经验,供网友分享。”

    http://blog.csdn.net/henrylubin/article/details/2047671

    扩展问题:如果Object在某时刻又被赋值为其他非item对象了呢?Property上加上属性[XmlElement(typeof(Item))]还是不够彻底,最好在类上加

    [XmlInclude(typeof(...)), XmlInclude(typeof(...))]

    所有的Attribute Class:

    http://msdn.microsoft.com/en-us/library/system.attribute.aspx#inheritanceContinued

  • 相关阅读:
    Objective-C 调用C++,C
    ios项目不能再用UDID了
    xcode 4 制作静态库详解
    Icon specified in the Info.plist not found under the top level app wrapper: Icon.png
    吼吼 尬English
    Redis
    处理android 经典蓝牙发送文件时接收包的问题
    Md5加密的文件流中是否会包含其md5值
    Android gradle buid failed case
    Android GDB 调试
  • 原文地址:https://www.cnblogs.com/dirichlet/p/3247040.html
Copyright © 2020-2023  润新知