Обнаружение несоответствия между именами параметров конструктора и именами свойств с неизменяемыми объектами - PullRequest
0 голосов
/ 24 мая 2018

Рассмотрим следующий изменяемый объект:

class SomePoco
{
    public int Id{get;set;}
    public string Name{get;set;}
}

Давайте рассмотрим его через Json.NET:

var p=new SomePoco{Id=4,Name="spender"};
var json=JsonConvert.SerializeObject(p);
var pr = JsonConvert.DeserializeObject<SomePoco>(json);
Console.WriteLine($"Id:{pr.Id}, Name:{pr.Name}");

Все хорошо.

Теперь давайте сделаемвывести неизменяемые значения POCO и значения подачи через конструктор:

class SomeImmutablePoco
{
    public SomeImmutablePoco(int id, string name)
    {
        Id = id;
        Name = name;
    }
    public int Id{get;}
    public string Name{get;}
}

... и снова обработать данные в обратном порядке:

var p = new SomeImmutablePoco(5, "spender's immutable friend");
var json = JsonConvert.SerializeObject(p);
var pr = JsonConvert.DeserializeObject<SomeImmutablePoco>(json);
Console.WriteLine($"Id:{pr.Id}, Name:{pr.Name}");

Все еще хорошо.

Теперь,давайте внесем небольшое изменение в наш неизменный класс, переименовав параметр конструктора:

class SomeImmutablePoco
{
    public SomeImmutablePoco(int pocoId, string name)
    {
        Id = pocoId;
        Name = name;
    }
    public int Id{get;}
    public string Name{get;}
}

затем:

var p = new SomeImmutablePoco(666, "diabolo");
var json = JsonConvert.SerializeObject(p);
var pr = JsonConvert.DeserializeObject<SomeImmutablePoco>(json);
Console.WriteLine($"Id:{pr.Id}, Name:{pr.Name}");

О, дорогой ... Похоже, Json.NET делает некоторые размышлениямагия над именами параметров нашего конструктора и сопоставление их с именами свойств в нашем POCO / json.Это означает, что нашему недавно десериализованному объекту не присваивается Id.Когда мы распечатываем Id, это 0.

Это плохо, и особенно трудно отследить.

Эта проблема может существовать в большой коллекции POCO.Как я могу автоматизировать поиск этих проблемных классов POCO?

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Вот код, который находит такие классы, используя отражение:

var types = new List<Type>() { typeof(SomeImmutablePoco) }; // get all types using reflection
foreach (var type in types)
{
    var props = type.GetProperties(bindingAttr: System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
    foreach (var ctor in type.GetConstructors())
    {
        foreach (var param in ctor.GetParameters())
        {
            if (!props.Select(prop => prop.Name.ToLower()).Contains(param.Name.ToLower()))
            {
                Console.WriteLine($"The type {type.FullName} may have problems with Deserialization");
            }
        }
    }
}
0 голосов
/ 24 мая 2018

Вы можете сопоставить вашу собственность json следующим образом:

class SomeImmutablePoco
    {
        public SomeImmutablePoco(int pocoId, string name)
        {


       Id = pocoId;
        Name = name;
    }

    [JsonProperty("pocoId")]
    public int Id { get; }
    public string Name { get; }
}
...