2016-03-28 6 views
1

Nach Stunden der Versuche und Forschung, ich bitte um Ihre Hilfe.C# - Newtonsoft: Generic Klasse für Client Response

Ich rufe eine öffentliche API, die die gleiche Struktur außer den zurückgegebenen Daten zurückgibt.

Beispiele, ruft die Ruhe, die abgerufen werden Stationen und Bezirke zurückkehren, diese beiden JSON Antworten:

Stationen Antwort:

"response" : { 
    "status": { "@attributes": {"code": "0", "message": "OK"} }, 
    "data" : { 
     "station": [{ 
      "number": "stationId", 
      "name": "stationName", 
      "address": "stationAddress", 
      "state": "1", 
      "latitude": "stationLat", 
      "longitude": "stationLong", 
      "slotsavailable": "10", 
      "bikesavailable": "20", 
      "pos": "0", 
      "district": "stationDistrict", 
      "lastupdate": "2016-03-28T11:47:08+02:00" 
     }, {...}, ...]} 
} 

Bezirke Antwort:

"response" : { 
    "status": { "@attributes": {"code": "0", "message": "OK"} }, 
    "data" : { "district": [{"id": "districtId", "name": "districtName"}, {...}, ...] } 
} 

ich verwende. NET 4.5/C# -Lösung mit Newtonsoft.Json, um den Aufruf auszuführen.

var result = await client.Execute<Response<ApiResponseDistrict>>(request); 
var result = await client.Execute<Response<ApiResponseStation>>(request); 

Mein erster Versuch, einen nicht generischen Aufruf zu machen war (erstellen voll: ich das Objekt machen will, auf die Client-Antwort abgebildet, generisch, so dass die Ausführung des Anrufs wird wie folgt vorgenommen werden Objekt durch zurückgegebene Daten), was ein Erfolg war.

Mein zweiter Versuch war ein generisches Objekt erstellt, damit ich die folgenden Klassen mit der JsonProperty der Bibliothek Newtonsoft gemacht:

public class ApiResponse<T> 
{ 
    [JsonProperty("response")] 
    public Response<T> Response { get; set; } 
} 

public class Response<T> 
{ 
    [JsonProperty("status")] 
    public Status Status { get; set; } 
    [JsonProperty("data")] 
    public Data<T> Data { get; set; } 
} 

public class Data<T> 
{ 
    public T ResponseData { get; set; } 
} 

public class ApiResponseDistrict 
{ 
    [JsonProperty("district")] 
    public List<District> Districts { get; set; } 
} 

public class District 
{ 
    [JsonProperty("id")] 
    public int Id { get; set; } 
    [JsonProperty("name")] 
    public string Name { get; set; } 
} 

An diesem Punkt, als ich den Anruf am Ausführung das Objekt Response valorisiert und auch seine Eigenschaft Status mit dem Wert wait, aber die Eigenschaft Data wird nie valorisiert (null).

Mein dritte Versuch war im zweiten Versuch fortsetzen, aber mit den JsonObject der Newtonsoft Bibliothek, die es (mit dem gleichen Ergebnis) gegeben hat:

[JsonObject("district")] 
public class ApiResponseDistrict 
{ 
    public List<District> Districts { get; set; } 
} 

Als ich Newtonsoft neu bin, würde ich möchte ich wissen, ob es möglich ist, generische Klassen zu verwenden, wie ich versuche, das vom Aufruf zurückgegebene Objekt abzubilden, oder muss ich ein komplettes Objekt für jede zurückgegebene "Daten" erstellen?

Vielen Dank für Ihre Antwort und Erklärungen oder Hinweise für mich, um die Antwort zu finden!

+0

Was ist die Definition für ResponseData und Status-Klassen? –

+0

Die Statusklasse ist eine Klasse, die ich auf die gleiche Weise wie die Klasse Data erstellt habe. ResponseData ist nur der Name der Eigenschaft mit dem Typ T, was im Fall meines Beispiels ApiResponseDistrict ist. – dtlvd

+0

Sind das die tatsächlichen Antworten, weil keine davon JSON ist. –

Antwort

1
public class Response<T> 
{ 
    [JsonProperty("status")] 
    public Status Status { get; set; } 
    [JsonProperty("data")] 
    public Data<T> Data { get; set; } 
} 

public class Data<T> 
{ 
    public T ResponseData { get; set; } 
} 

Diese weitere Schicht zwischen den Daten hinzufügt, so dass eine Reaktion würde wie folgt aussehen:

{ 
    "Status": …, 
    "Data": { 
     "ResponseData": { 
      <The actual type T> 
     } 
    } 
} 

Stattdessen möchten Sie, dass ResponseData Ebene entfernen:

public class Response<T> 
{ 
    [JsonProperty("status")] 
    public Status Status { get; set; } 
    [JsonProperty("data")] 
    public T Data { get; set; } 
} 

So zum Beispiel , für die JSON oben, würden Sie eine StationResponseData Klasse haben:

public class StationResponseData 
{ 
    public List<Station> Stations 
    { get; set; } 
} 

Und dann würden Sie das JSON als Response<StationResponseData> deserialisieren. Die Klasse Station würde dann diese Eigenschaften für number, name, address usw. enthalten.

+0

Danke @poke, es war in der Tat der ResponseData-Level, der störte! Ich dachte, dass die Ebene wurde nur hinzugefügt, wenn Sie die JsonProperty angeben, aber es scheint, dass es nicht ist. – dtlvd