无法使用特定名称反序列化属性

时间:2016-11-24 10:29:00

标签: c# serialization datacontractserializer

我在C#中使用DataContractSerializer将xml文件反序列化为对象,一切正常:)

当我向我的类和xml文件添加新属性时,我的问题就开始了。每次我反序列化文件时,我的新属性名称为EncryptionKey,属性值保持null,但是当我将xml元素和属性的名称更改为anEncryptionKey时,它正确地反序列化而不更改其他任何内容代码。

实际上我尝试了许多属性名称的选项,例如EncryptKeyEncrypt等等,但我最终得到anEncryptionKey

也许对属性名称或类似的东西有一些约束,或者我只需要更多的咖啡因来弄明白。

Xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<KioskSettings xmlns="http://schemas.datacontract.org/2004/07/Proxies" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <ID>20198</ID>
  <HeartBeatInterval>1</HeartBeatInterval>
  <ServerURL></ServerURL>
  <EncryptionKey>abcd</EncryptionKey>
</KioskSettings>

我用来将文件反序列化为对象的代码:

private KioskSettings ReadEngineSettingsFromSimulatorXmlFile()
 {
    KioskSettings engineSettings = new KioskSettings();
    DataContractSerializer serializer = new DataContractSerializer(typeof(KioskSettings));
    FileStream fs = new FileStream(@"c:\simulation.xml", FileMode.Open);
    XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
    while (reader.Read())
    {
        switch (reader.NodeType)
        {
            case XmlNodeType.Element:
                if (serializer.IsStartObject(reader))
                {
                    engineSettings = (KioskSettings)serializer.ReadObject(reader);
                }
                break;
        }
    }

    fs.Flush(); fs.Close();
    reader.Close(); 
    reader = null;
    serializer = null;
    return engineSettings;
}

KioskSettings类:

 public class KioskSettings
 {
    public string ID { get; set; }

    public int HeartBeatInterval {get; set;}

    public string ServerURL {get; set;}

    public string EncryptionKey { get; set; }

 }

注意:上面的代码可能包含一些语法错误,因为我修改它以使其缩短。

1 个答案:

答案 0 :(得分:2)

您需要确保XML节点按字母顺序排列:

<?xml version="1.0" encoding="utf-8" ?>
<KioskSettings xmlns="http://schemas.datacontract.org/2004/07/Proxies" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <EncryptionKey>abcd</EncryptionKey>
  <HeartBeatInterval>1</HeartBeatInterval>
  <ID>20198</ID>
  <ServerURL></ServerURL>
</KioskSettings>

使用以下代码序列化KioskSettings对象,并确保您的XML采用相同的格式:

public static string DataContractSerializeObject<T>(T objectToSerialize)
{
    using (MemoryStream memStm = new MemoryStream())
    {
        var serializer = new DataContractSerializer(typeof(T));
        serializer.WriteObject(memStm, objectToSerialize);

        memStm.Seek(0, SeekOrigin.Begin);

        using (var streamReader = new StreamReader(memStm))
        {
            string result = streamReader.ReadToEnd();
            return result;
        }
    }
}

如果您需要保留特定订单,请在类属性上指定DataMember属性 - Data Member Order,例如

[DataContract]
public class KioskSettings
{
    [DataMember(Order = 1)]
    public string ID { get; set; }

    [DataMember(Order = 2)]
    public int HeartBeatInterval { get; set; }

    [DataMember(Order = 3)]
    public string ServerURL { get; set; }

    [DataMember(Order = 4)]
    public string EncryptionKey { get; set; }
}