【问题标题】:DataContractSerializer does not properly deserialize, values for methods in object are missingDataContractSerializer 没有正确反序列化,对象中方法的值丢失
【发布时间】:2010-12-11 16:22:39
【问题描述】:

我的一些类

[Serializable]
[DataContract(Namespace = "")]
public class SomeClass
{
    [DataMember]
    public string FirstName
    { 
        get; set;
    }

    [DataMember]
    public string LastName
    { 
        get; set;
    }

    [DataMember]
    private IDictionary<long, string> customValues;
    public IDictionary<long, string> CustomValues
    {
        get { return customValues; }
        set { customValues = value; }
    }
}

我的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
 <SomeClass>
 <FirstName>John</FirstName>
 <LastName>Smith</LastName>
 <CustomValues>
    <Value1>One</Value1>
    <Value2>Two</Value2>
 </CustomValues >
 </SomeClass>

但我的问题出在类上,我只在反序列化时为我的方法获取一些数据。

var xmlRoot = XElement.Load(new StreamReader(
                    filterContext.HttpContext.Request.InputStream,
                    filterContext.HttpContext.Request.ContentEncoding));
XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlRoot.CreateReader());
 DataContractSerializer ser = new DataContractSerializer(typeof(SomeClass));
//Deserialize the data and read it from the instance.
SomeClass someClass = (SomeClass)ser.ReadObject(reader, true);

所以当我检查“someClass”时,FirstName 的值为 john,但 LastName 的值为 null。

神秘的是我怎样才能得到一些数据,而不是类的所有数据。 所以 DataContractSerializer 在反序列化时不会从 xml 中提取所有数据。

我是不是做错了什么。

感谢任何帮助。提前致谢。

如果有人有同样的问题或有解决方案,请告诉我

【问题讨论】:

  • DataMember 属性不应该在公共财产上而不是在私有财产上吗?

标签: c# serialization datacontractserializer


【解决方案1】:

好吧,在玩了很多次之后,我找到了自己的答案……它必须按字母顺序排列。 所以如果类有

[Serializable]
[DataContract(Namespace = "")]    
public class SomeClass
{
    [DataMember]
    public string FirstName
    { 
        get; set;
    }

    [DataMember]
    public string LastName
    { 
        get; set;
    }

    [DataMember]
    private IDictionary<long, string> customValues;
    public IDictionary<long, string> CustomValues
    {
        get { return customValues; }
        set { customValues = value; }
    }
}

那么 xml 应该按字母顺序定义。

<?xml version="1.0" encoding="UTF-8"?>
 <SomeClass>
 <CustomValues>
    <Value1>One</Value1>
    <Value2>Two</Value2>
 </CustomValues >
 <FirstName>John</FirstName>
 <LastName>Smith</LastName>
 </SomeClass>

为什么h...必须按字母顺序排列?

【讨论】:

  • 感谢您发布这一惊人的知识。我一直在敲打“几乎”工作了几个小时的相同代码。快速的架构更改,它的工作原理。您一定想知道为什么产品中没有更清楚地记录这一点。 +1
  • 哇,我也只是浪费了几个小时试图找到解决方案。如果 Web 服务以与 WSDL 规范不同的顺序返回 XML 元素,这会导致一些严重的问题 - 在这种情况下,由 SvcUtil 生成的代理将具有错误的顺序并且反序列化会静默失败。
  • @Oenotria 我刚刚花了 2 个小时来解决同样的问题。这是不真实的。微软一定充满了十足的白痴。他们必须从排序列表中迭代对象属性,并检查当前 XML 节点是否包含与该属性对应的子节点。他们正在倒退。迭代 XML 节点,并查找与该属性对应的属性是否存在。这太恶心了。为了满足微软的序列化,我已经过头了。
  • 在 PortableRest 中,我们通过使用 Xlinq 清理 XML,然后在传递给序列化程序之前按字母顺序对 XML 节点进行排序,从而解决了这个问题。以下是我们如何使用它:github.com/advancedrei/PortableRest/blob/master/src/…。如果您必须处理 Web 服务,您可以使用 PortableRest 将它们完全调用为 REST,我们会自动为您完成此操作。
【解决方案2】:

这就是Order 属性的用途;如果您无法控制反序列化的 XML,这是我所知道的唯一解决方法。

在你的第一个例子中

[Serializable]
[DataContract(Namespace = "")]
public class SomeClass
{
    [DataMember(Order = 0)]
    public string FirstName
    { 
        get; set;
    }

    [DataMember(Order = 1)]
    public string LastName
    { 
        get; set;
    }

    [DataMember(Order = 2)]
    private IDictionary customValues;
    public IDictionary CustomValues
    {
        get { return customValues; }
        set { customValues = value; }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多