Как подделать тип в JSON.NET при сериализации out?

#c# #json.net

#c# #json.net

Вопрос:

допустим, у меня есть

 public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
    }
 

теперь, если я создам анонимный тип, например…

 var p = new Person() {FirstName = "bob",
                      LastName = "builder",
                      PhoneNumber = "0800 YESWECAN"};

var anon = new {p.FirstName, p.LastName};
 

с JSON.NET , когда у вас есть TypeNameHandling = TypeNameHandling .Объекты, он будет сериализовать (а затем использовать для десерилизации) тип. Что я хочу сделать, так это подделать тип в классе annoymous, чтобы при его сериализации он выглядел как объект «Person».

Есть ли хороший простой способ сделать это?

ПРИМЕЧАНИЕ: Он ДОЛЖЕН иметь Json.Чистая информация о типе в формате json ( $type ). Таким образом, ответ LBs не решает проблему, на самом деле я мог бы просто использовать средства .net framework json для выполнения именно этого.

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

1. По какой-либо причине вы не смогли использовать new Person { FirstName = "", LastName = "" } ?

2. да …… у этого все равно будет объект с «номером телефона». Для этого экземпляра я не хочу, чтобы номер телефона был сериализован (это надуманный пример, чтобы задать вопрос, на самом деле объектные модели сложны). Я обновил пример, чтобы попытаться сделать его более понятным

Ответ №1:

Вы можете сериализовать как

 string str = JsonConvert.SerializeObject(new { FirstName = "aaa", LastName = "bbb" })
 

и вы получите строку, которая выглядит как объект Person

 {"FirstName":"aaa","LastName":"bbb"}
 

Поскольку Json не содержит информации о типе, вы можете десериализовать его обратно в Person

 var person = JsonConvert.DeserializeObject(str, typeof(Person));
 

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

1. Я не верю, что это правильный ответ. Я думаю, что оператору нужен объект, сериализованный с $type установленным Person значением, чтобы его можно было десериализовать позже без необходимости знать тип объекта.

2. I don't believe this is the right answer , this isn't the right answer @KeithNicholas @CAbbott Что с этим не так? Чего вы действительно ожидаете? Обоснуйте свои ответы

3. потому что, когда объектная модель более сложная, вам нужна информация о типе (особенно при сублимации ). Мой вопрос о том, как ПОДДЕЛАТЬ информацию о типе с помощью анонимных типов.

4. because when the object model is more complex, you need the type information это не ответ. Возможно, вам это не понадобится. Просто задайте свою реальную проблему и найдите ее решение. Он думает, что это какая-то проблема XY perlmonks.org/?node_id=542341

5. Из Json. СЕТЕВАЯ документация: TypeNameHandling контролирует, является ли Json. NET включает имена типов .NET во время сериализации с помощью свойства $type и считывает имена типов .NET из этого свойства, чтобы определить, какой тип создавать во время десериализации .

Ответ №2:

чтобы подделать это, я могу ввести контракт на изменение имени свойства при выводе json … например…

  public class FakeTypeContractResolver : DefaultContractResolver
    {        
        protected override string ResolvePropertyName(string propertyName)
        {
            return propertyName == "_type_" ? "$type" : propertyName;
        }
    }
 

итак, если у вас есть json.net настройки десериализатора установлены на

 TypeNameHandling = TypeNameHandling.Objects
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
 

вы можете создать раздражающий тип, подобный следующему,

 var x = new 
{
     _type_ = typeof(Person).AssemblyQualifiedName,
     p.FirstName, 
     p.LastName
}
 

Который будет притворяться «Человеком» в информации о типе, что означает, что если вы его десериализуете, вы получите объект person.

ПРИМЕЧАНИЕ: настройки serializer to json должны быть настроены так, чтобы не сериализовать информацию о типе out, когда вы ее подделываете.