346 votes

Comment désérialiser un JObject en objet .NET ?

J'utilise volontiers le Bibliothèque JSON de Newtonsoft . Par exemple, je créerais un JObject à partir d'un objet .NET, dans ce cas une instance de Exception (qui peut être ou non une sous-classe).

if (result is Exception)
    var jobjectInstance = JObject.FromObject(result);

maintenant je sais que la bibliothèque peut désérialiser du texte JSON (c'est-à-dire une chaîne) vers un objet

// only works for text (string)
Exception exception = JsonConvert.DeserializeObject<Exception>(jsontext); 

mais ce que je cherche, c'est :

// now i do already have an JObject instance
Exception exception = jobjectInstance.????

Eh bien, il est clair que je peux partir de là. JObject en texte JSON et ensuite utiliser la fonctionnalité de désérialisation, mais cela me semble inversé.

682voto

Tien Do Points 1262

Selon cette poste c'est beaucoup mieux maintenant :

// pick out one album
JObject jalbum = albums[0] as JObject;

// Copy to a static Album instance
Album album = jalbum.ToObject<Album>();

Documentation : Convertir JSON en un type

11 votes

Des idées sur les implications en termes de performances ? La réflexion sera-t-elle utilisée à chaque fois ?

2 votes

Est-il possible de faire cela avec un JsonConverter personnalisé ?

4 votes

Merci pour l'astuce. Elle m'a beaucoup aidé. Permettez-moi d'ajouter quelque chose : dans une méthode générique où j'utilise le type T j'avais besoin de quelque chose comme result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T); pour le convertir avec succès (note - value est un objet provenant d'une base de données qui peut être un JObject ou autre chose, auquel cas le résultat doit être nul).

54voto

Sebastian Godelet Points 1093

Dans la documentation, j'ai trouvé ceci :

JObject o = new JObject(
   new JProperty("Name", "John Smith"),
   new JProperty("BirthDate", new DateTime(1983, 3, 20))
);

JsonSerializer serializer = new JsonSerializer();
Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person));

Console.WriteLine(p.Name);

La définition de la classe pour Person doit être compatible avec les éléments suivants :

class Person {
    public string Name { get; internal set; }
    public DateTime BirthDate { get; internal set; }
}

Si vous utilisez une version récente de JSON.net y n'ont pas besoin de sérialisation personnalisée, veuillez voir La réponse de Tien Do ce qui est plus concis.

3 votes

J'avais besoin d'utiliser cette approche, plutôt que le raccourci, pour pouvoir transmettre des paramètres de sérialisation personnalisés.

3voto

Ivan Lopez Points 69

Trop tard, juste au cas où quelqu'un chercherait une autre voie :

void Main()
{
    string jsonString = @"{
  'Stores': [
    'Lambton Quay',
    'Willis Street'
  ],
  'Manufacturers': [
    {
      'Name': 'Acme Co',
      'Products': [
        {
          'Name': 'Anvil',
          'Price': 50
        }
      ]
    },
    {
      'Name': 'Contoso',
      'Products': [
        {
          'Name': 'Elbow Grease',
          'Price': 99.95
        },
        {
          'Name': 'Headlight Fluid',
          'Price': 4
        }
      ]
    }
  ]
}";

    Product product = new Product();
    //Serializing to Object
    Product obj = JObject.Parse(jsonString).SelectToken("$.Manufacturers[?(@.Name == 'Acme Co' && @.Name != 'Contoso')]").ToObject<Product>();

    Console.WriteLine(obj);
}

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X