So deserialisieren Sie ein JObject in ein .NET-Objekt


240

Ich benutze gerne die Newtonsoft JSON-Bibliothek . Zum Beispiel würde ich ein JObjectaus einem .NET-Objekt erstellen , in diesem Fall eine Instanz von Exception (möglicherweise eine Unterklasse oder nicht).

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

Jetzt weiß ich, dass die Bibliothek JSON-Text (dh eine Zeichenfolge) für ein Objekt deserialisieren kann

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

aber was ich suche ist:

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

Nun, es ist klar, dass ich von JObjectzurück zu JSON-Text wechseln und dann die Deserialisierungsfunktion verwenden kann, aber das scheint mir rückwärts zu sein.

Antworten:


489

Laut diesem Beitrag ist es jetzt viel besser:

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

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

Dokumentation: Konvertieren Sie JSON in einen Typ


10
Irgendwelche Ideen zu den Auswirkungen auf die Leistung hier? Wird jedes Mal Reflexion verwendet?
— Shaun Rowan

1
Ist dies mit einem benutzerdefinierten JsonConverter möglich?
— Justin Skiles

3
Danke für den Hinweis. Es hat mir sehr geholfen. Lassen Sie mich etwas hinzufügen: In einer generischen Methode, in der ich type verwende T, benötigte ich etwas result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);, um es erfolgreich zu konvertieren (Hinweis - valueist ein Objekt, das aus einer Datenbank stammt, die ein JObject sein könnte, oder etwas anderes. In diesem Fall sollte das Ergebnis null sein).
— Matt

@ShaunRowan Beim Herumspielen mit Code in Linqpad sieht es so aus, als würde Reflexion verwendet, um die Eigenschaft auf derselben "Ebene" des Zielobjekts wie das entsprechende Feld im JSON-Objekt abzugleichen. Der Name Ihrer Eigenschaft muss mit dem Namen des JSON-Felds übereinstimmen, und der Typ Ihrer Eigenschaft muss ein kompatibler Typ sein.
— BobbyA

und verwenden jobject.ToObject(myObject.GetType())Sie, wenn Sie den Objekttyp nicht kennen.
— Tohid

45

Aus der Dokumentation habe ich dies gefunden

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);

Die Klassendefinition für Personsollte mit folgenden Komponenten kompatibel sein:

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

Bearbeiten

Wenn Sie eine neuere Version von JSON.net verwenden und keine benutzerdefinierte Serialisierung benötigen, lesen Sie bitte die Antwort von TienDo oben (oder unten, wenn Sie mich positiv bewerten: P), die präziser ist.


2
Ich musste diesen Ansatz anstelle der Kurzform verwenden, um benutzerdefinierte Serialisierungseinstellungen übergeben zu können.
— Justin Caldicott

Genau ans ich suche
— Mark-VII

2

Zu spät, nur für den Fall, dass jemand nach einem anderen Weg sucht:

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; }
}

Dies sieht genauso aus wie die akzeptierte Antwort .
— Jpaugh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.