DataContract在没有DataContractAttribute的情况下工作(直到混淆)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DataContract在没有DataContractAttribute的情况下工作(直到混淆)相关的知识,希望对你有一定的参考价值。

我有一个由DataContract表示的以下分层JSON对象,我可以使用javascriptSerializer正常解析

[DataContract]
public class ClassOuter{
    [DataMember(Name = "stringProperty1")]
    public string stringProperty1 {get;set;}

    [DataMember(Name = "objectProperty")]
    public ClassInner objectProperty {get;set;}
}

//NOTE:No DataContract Attribute here!
public class ClassInner{
    [DataMember(Name = "stringProperty2")]
    public string stringProperty2 {get;set;}
}

但是当我打电话时

string inputText = "{"stringProperty1":"Hello","objectProperty":{"stringProperty2":"World"}}";
ClassOuter myObject = new JavascriptSerializer().Deserialize<ClassOuter>(inputText);
Console.WriteLine(myObject.stringProperty2);

一切正常。

但是,在构建之后通过混淆器运行应用程序,stringProperty2变为null。 *不能说什么混淆器,对不起!

没有来自CodeAnalysis的警告。我对编译器不是很熟悉,但是我的猜测是:编译器识别意图并在内部建立链接,尽管没有DataContract属性。但是,它没有进行某种内部标记,因此混淆器可以自由地混淆它并且链接断开。如果它只是一块连续的记忆,我猜想事情会比他们更难打破,而不仅仅是成为null

任何人都可以验证或质疑我的天真假设吗?

(为DataContract添加ClassInner属性可以解决问题,即使是混淆!)

答案

任何人都可以验证或质疑我的天真假设吗?

未经过模糊处理,它将在没有[DataContract]的情况下工作,因为发生的情况是序列化程序将回退到不使用属性并仅通过属性名称对其进行序列化。它们与您的属性相同,因此您不会注意到这一点。你应该能够通过给出没有正确的[DataMember]另一个[DataContract]文本的Name来验证,序列化程序仍将使用属性名称并忽略该属性。这些属性可以成对使用。设置两者或回退到“无”。

public class ClassInner
{
    // This is ignored because no [DataContract] was found
    [DataMember(Name = "nonexistentProperty")] 

    // This will still be set unobfuscated because the property name matches
    public string stringProperty2 { get; set; }
}

因此,当您对其进行模糊处理时,属性名称会发生​​变化。如果没有[DataContract],序列化程序将回退到属性并找到他无法与输入匹配的随机字母组合。因此,你会得到null

以上是关于DataContract在没有DataContractAttribute的情况下工作(直到混淆)的主要内容,如果未能解决你的问题,请参考以下文章

DataContract,默认 DataMember 值

DataContract with Json.Net

如何在 WCF 中将接口标记为 DataContract

DataContract,默认 DataMember 值将 api 在应用程序之间工作

在 WCF 中命名通用 DataContract

数据契约[DataContract]