it-swarm.com.de

JSON-Daten mit JSON.NET in C # deserialisieren

Ich bin relativ neu in der Arbeit mit C # - und JSON-Daten und suche Unterstützung. Ich verwende C # 3.0 mit .NET3.5SP1 und JSON.NET 3.5r6.

Ich habe eine definierte C # -Klasse, die ich aus einer JSON-Struktur füllen muss. Nicht jede JSON-Struktur für einen Eintrag, der vom Webdienst abgerufen wird, enthält jedoch alle möglichen Attribute, die in der C # -Klasse definiert sind.

Ich habe den scheinbar falschen, harten Weg beschritten und jeden Wert einzeln aus dem JObject herausgesucht und die Zeichenfolge in die gewünschte Klasseneigenschaft umgewandelt.

JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);

MyAccount.EmployeeID = (string)o["employeeid"][0];

Was ist der beste Weg, um eine JSON-Struktur in die C # -Klasse zu deserialisieren und mögliche fehlende Daten aus der JSON-Quelle zu verarbeiten?

Meine Klasse ist definiert als:

  public class MyAccount
  {

    [JsonProperty(PropertyName = "username")]
    public string UserID { get; set; }

    [JsonProperty(PropertyName = "givenname")]
    public string GivenName { get; set; }

    [JsonProperty(PropertyName = "sn")]
    public string Surname { get; set; }

    [JsonProperty(PropertyName = "passwordexpired")]
    public DateTime PasswordExpire { get; set; }

    [JsonProperty(PropertyName = "primaryaffiliation")]
    public string PrimaryAffiliation { get; set; }

    [JsonProperty(PropertyName = "affiliation")]
    public string[] Affiliation { get; set; }

    [JsonProperty(PropertyName = "affiliationstatus")]
    public string AffiliationStatus { get; set; }

    [JsonProperty(PropertyName = "affiliationmodifytimestamp")]
    public DateTime AffiliationLastModified { get; set; }

    [JsonProperty(PropertyName = "employeeid")]
    public string EmployeeID { get; set; }

    [JsonProperty(PropertyName = "accountstatus")]
    public string AccountStatus { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpiration")]
    public DateTime AccountStatusExpiration { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpmaxdate")]
    public DateTime AccountStatusExpirationMaxDate { get; set; }

    [JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
    public DateTime AccountStatusModified { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpnotice")]
    public string AccountStatusExpNotice { get; set; }

    [JsonProperty(PropertyName = "accountstatusmodifiedby")]
    public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }

    [JsonProperty(PropertyName = "entrycreatedate")]
    public DateTime EntryCreatedate { get; set; }

    [JsonProperty(PropertyName = "entrydeactivationdate")]
    public DateTime EntryDeactivationDate { get; set; }

  }

Ein Beispiel für den zu analysierenden JSON ist:

{
    "givenname": [
        "Robert"
    ],
    "passwordexpired": "20091031041550Z",
    "accountstatus": [
        "active"
    ],
    "accountstatusexpiration": [
        "20100612000000Z"
    ],
    "accountstatusexpmaxdate": [
        "20110410000000Z"
    ],
    "accountstatusmodifiedby": {
        "20100214173242Z": "tdecker",
        "20100304003242Z": "jsmith",
        "20100324103242Z": "jsmith",
        "20100325000005Z": "rjones",
        "20100326210634Z": "jsmith",
        "20100326211130Z": "jsmith"
    },
    "accountstatusmodifytimestamp": [
        "20100312001213Z"
    ],
    "affiliation": [
        "Employee",
        "Contractor",
        "Staff"
    ],
    "affiliationmodifytimestamp": [
        "20100312001213Z"
    ],
    "affiliationstatus": [
        "detached"
    ],
    "entrycreatedate": [
        "20000922072747Z"
    ],
    "username": [
        "rjohnson"
    ],
    "primaryaffiliation": [
        "Staff"
    ],
    "employeeid": [
        "999777666"
    ],
    "sn": [
        "Johnson"
    ]
}
140
user305145

Verwenden

var rootObject =  JsonConvert.DeserializeObject<RootObject>(string json);

Erstellen Sie Ihre Klassen mit JSON 2 C #


Json.NET-Dokumentation: JSON mit Json.NET serialisieren und deserialisieren

272
w.donk

Haben Sie versucht, die generische DeserializeObject-Methode zu verwenden?

JsonConvert.DeserializeObject<MyAccount>(myjsondata);

Fehlende Felder in den JSON-Daten sollten einfach NULL bleiben.

AKTUALISIEREN:

Wenn die JSON-Zeichenfolge ein Array ist, versuchen Sie Folgendes:

var jarray = JsonConvert.DeserializeObject<List<MyAccount>>(myjsondata);

jarray sollte dann ein List<MyAccount> sein.

EIN ANDERES UPDATE:

Die Ausnahme, die Sie erhalten, stimmt nicht mit einem Array von Objekten überein. Ich glaube, der Serializer hat Probleme mit Ihrer vom Wörterbuch eingegebenen Eigenschaft accountstatusmodifiedby.

Versuchen Sie, die Eigenschaft accountstatusmodifiedby von der Serialisierung auszuschließen, und prüfen Sie, ob dies hilfreich ist. In diesem Fall müssen Sie diese Eigenschaft möglicherweise anders darstellen.

Dokumentation: JSON mit Json.NET serialisieren und deserialisieren

77
Dave Swersky

Antwort reproduziert von https://stackoverflow.com/a/10718128/776476

Sie können den Typ C # dynamic verwenden, um die Arbeit zu vereinfachen. Diese Technik vereinfacht auch das Refactoring, da es nicht auf magischen Ketten beruht.

Json

Die folgende Zeichenfolge json ist eine einfache Antwort auf einen http-API-Aufruf und definiert zwei Eigenschaften: Id und Name.

{"Id": 1, "Name": "biofractal"}

C #

Verwenden Sie JsonConvert.DeserializeObject<dynamic>(), um diesen String in einen dynamischen Typ zu deserialisieren, und greifen Sie dann einfach auf die gewohnte Weise auf seine Eigenschaften zu.

var results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

Hinweis: Der NuGet-Link für die NewtonSoft-Assembly lautet http://nuget.org/packages/newtonsoft.json . Vergessen Sie nicht, Folgendes hinzuzufügen: using Newtonsoft.Json;, Um auf diese Klassen zuzugreifen.

49
biofractal

Sie können verwenden:

JsonConvert.PopulateObject(json, obj);

hier: json ist der json-String, obj ist das Zielobjekt. Siehe: Beispiel

Hinweis: PopulateObject() löscht die Listendaten von obj nicht. Nach Populate() enthält das Listenmitglied obj's Seine ursprünglichen Daten und Daten aus der json-Zeichenfolge

8
bbants

Aufbauend auf der Antwort von bbant ist dies meine Komplettlösung zur Deserialisierung von JSON über eine entfernte URL.

using Newtonsoft.Json;
using System.Net.Http;

namespace Base
{
    public class ApiConsumer<T>
    {
        public T data;
        private string url;

        public CalendarApiConsumer(string url)
        {
            this.url = url;
            this.data = getItems();
        }

        private T getItems()
        {
            T result = default(T);
            HttpClient client = new HttpClient();

            // This allows for debugging possible JSON issues
            var settings = new JsonSerializerSettings
            {
                Error = (sender, args) =>
                {
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
            };

            using (HttpResponseMessage response = client.GetAsync(this.url).Result)
            {
                if (response.IsSuccessStatusCode)
                {
                    result = JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result, settings);
                }
            }
            return result;
        }
    }
}

Die Verwendung wäre wie folgt:

ApiConsumer<FeedResult> feed = new ApiConsumer<FeedResult>("http://example.info/feeds/feeds.aspx?alt=json-in-script");

Wobei FeedResult die Klasse ist, die mit Xamasoft JSON Class Generator generiert wurde

Hier ist ein Screenshot der Einstellungen, die ich verwendet habe, wobei seltsame Eigenschaftsnamen berücksichtigt wurden, die in Webversion nicht berücksichtigt werden konnten.

Xamasoft JSON Class Generator

3
Kyle Falconer

Ich habe festgestellt, dass ich mein Objekt falsch gebaut habe. Ich habe http://json2csharp.com/ verwendet, um meine Objektklasse aus dem JSON zu generieren. Sobald ich das richtige Objekt hatte, konnte ich ohne Probleme zaubern. Norbit, Noob Fehler. Dachte, ich würde es hinzufügen, falls Sie das gleiche Problem haben.

1
Adam

Sie können versuchen, einige der Klassengeneratoren online auf weitere Informationen zu überprüfen. Ich glaube jedoch, dass einige der Antworten nützlich waren. Hier ist mein Ansatz, der nützlich sein kann.

Der folgende Code wurde mit einer dynamischen Methode erstellt.

dynObj = (JArray)JsonConvert.DeserializeObject(nvm);

        foreach (JObject item in dynObj)
        {
            foreach (JObject trend in item["trends"])
            {
         Console.WriteLine("{0}-{1}-{2}", trend["query"], trend["name"], trend["url"]);

            }
        }

Mit diesem Code können Sie grundsätzlich auf Mitglieder zugreifen, die in der Json-Zeichenfolge enthalten sind. Nur ein anderer Weg ohne die Notwendigkeit der Klassen. query, trend und url sind die in der Json-Zeichenfolge enthaltenen Objekte.

Sie können auch diese Website verwenden. Traue den Klassen nicht zu 100%, aber du bekommst die Idee.

1
Edward Newgate

Vorausgesetzt, Ihre Beispieldaten sind korrekt, Ihr Vorname und andere in Klammern gesetzte Einträge sind Arrays in JS ... Sie möchten List für diese Datentypen verwenden. und Liste für say accountstatusexpmaxdate ... Ich denke, in Ihrem Beispiel sind die Daten jedoch falsch formatiert, sodass Sie unsicher sind, was in Ihrem Beispiel noch falsch ist.

Dies ist ein alter Beitrag, wollte aber die Themen zur Kenntnis nehmen.

0
Tracker1