DataContract работает без DataContractAttribute (до запутывания) - PullRequest
0 голосов
/ 05 марта 2019

У меня есть следующий многоуровневый объект 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 Ответ

0 голосов
/ 05 марта 2019

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

Необъяснимо, это будет работать без [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.

...