DataContract работает без DataContractAttribute (до обфускации)

#c# #.net #obfuscation

#c# #.net #обфускация

Вопрос:

У меня есть следующий многоуровневый объект JSON, представленный DataContract , который я могу нормально проанализировать, используя 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 становится нулевым. * Не могу сказать, какой обфускатор, извините!

Никаких предупреждений от CodeAnalysis. Я не очень знаком с компиляторами, но вот мое предположение: компилятор распознает намерение и создает ссылку внутренне, несмотря на отсутствие DataContract атрибута. Однако он не создает какой-либо внутренней разметки, поэтому обфускатор может свободно перемешивать его, и ссылка прерывается. Однако, если бы это был просто блок непрерывной памяти, я бы предположил, что все было бы намного сложнее, чем сейчас, а не просто становилось null

Кто-нибудь может проверить или оспорить мою наивную гипотезу?

(Добавление DataContract атрибута для ClassInner решает проблему даже при обфускации!)

Ответ №1:

Кто-нибудь может проверить или оспорить мою наивную гипотезу?

Без обфускации он будет работать без [DataContract] , потому что в результате сериализатор просто вернется к отказу от использования атрибутов и сериализует их только по именам свойств. Они идентичны вашему атрибуту, поэтому вы этого не замечаете. Вы должны быть в состоянии убедиться, что, передавая [DataMember] текст, который пришел без надлежащего [DataContract] другого Name текста, сериализатор по-прежнему будет использовать имя свойства и игнорировать атрибут. Эти атрибуты работают как пара. Установите оба параметра или вернитесь к «none».

 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 .

Комментарии:

1. Имеет смысл. Большое вам спасибо!