Je crée un wrapper ActiveCampaign V1.1 pour C # .NET et crée une classe qui répertorie les ContactLists en utilisant ( https://www.activecampaign.com/api/example.php?call=list_list )
L'objet de réponse renvoyé après JsonConvert.DeserializeObject
a des propriétés non-list remplies, mais la partie liste du JSON n'est pas convertie.
J'ai essayé les implémentations BasicListResponse
suivantes: p >
{ "0": { "id": "1", "name": "xxxxx xxxxxx xxxxxxx", "cdate": "2019-10-27 22:43:23", "private": "0", "userid": "1", "subscriber_count": 1 }, "1": { "id": "2", "name": "yyyyy yyyyy yyyyy", "cdate": "2019-10-27 22:44:03", "private": "0", "userid": "1", "subscriber_count": 0 }, "result_code": 1, "result_message": "Success: Something is returned", "result_output": "json" }
J'ai également essayé d'utiliser json2csharp ou VS> Coller spécial mais la sortie a des classes numérotées plutôt qu'une liste d'objets.
La réponse JSON est la suivante:
public class Result { [JsonProperty("result_code")] public int ResultCode { get; set; } [JsonProperty("result_message")] public string ResultMessage { get; set; } [JsonProperty("result_output")] public string ResultOutput { get; set; } } public class BasicListResponse : Result { public Dictionary<string, BasicList> list { get; set; } } public class BasicList { [JsonProperty("id")] public string Id { get; set; } [Required] [JsonProperty("name")] public string Name { get; set; } [JsonProperty("cdate")] public DateTime CreatedOn { get; set; } [JsonProperty("private")] public bool Private { get; set; } [JsonProperty("userid")] public string UserId { get; set; } [JsonProperty("subscriber_count")] public int SubscriberCount { get; set; } }
J'ai extrait le Dictionary
dans le wrapper mais la liste est toujours NULL.
Si je re-sérialise la BasicListResponse
, les résultats sont les suivants s
{"list": null, "result_code": 1, "result_message": "Success: Quelque chose est retourné", "result_output": "json"}
p>
Je m'attends à ce que la BasicListResponse
soit utilisée comme un objet racine contenant un List / Array avec trois propriétés de chaîne result_ *
.
I apprécier toute aide pour résoudre ce problème.
3 Réponses :
Ce n'est pas la solution la plus élégante, mais vous pouvez structurer vos classes comme ceci:
result_code=1,result_message=Success: Something is returned,result_output=json Id=1,Name=xxxxx xxxxxx xxxxxxx,CDate=27/10/2019 10:43:23 PM,Private=0,UserId=1,SubscriberCount=1 Id=2,Name=yyyyy yyyyy yyyyy,CDate=27/10/2019 10:44:03 PM,Private=0,UserId=1,SubscriberCount=0
Ensuite, vous pouvez désérialiser votre json et mapper vos IDictionary
IEnumerable
. Notez que JsonExtensionData
doit être IDictionary
dans ce cas.
var deserializedJson = JsonConvert.DeserializeObject<Results>(json); var results = deserializedJson .Items .Select(entry => new Result { Id = (long)entry.Value["id"], Name = (string)entry.Value["name"], Cdate = DateTime.TryParse((string)entry.Value["cdate"], out var cdate) ? cdate : DateTime.MinValue, Private = (long)entry.Value["private"], UserId = (long)entry.Value["userid"], SubscriberCount = (long)entry.Value["subscriber_count"] }); Console.WriteLine($"result_code={deserializedJson.ResultCode},result_message={deserializedJson.ResultMessage},result_output={deserializedJson.ResultOutput}"); foreach (var result in results) { Console.WriteLine(result.ToString()); }
Sortie :
public class Results { [JsonExtensionData] public IDictionary<string, JToken> Items; [JsonProperty("result_code")] public long ResultCode { get; set; } [JsonProperty("result_message")] public string ResultMessage { get; set; } [JsonProperty("result_output")] public string ResultOutput { get; set; } } public class Result { public long Id { get; set; } public string Name { get; set; } public DateTime Cdate { get; set; } public long Private { get; set; } public long UserId { get; set; } public long SubscriberCount { get; set; } public override string ToString() { return $"Id={Id},Name={Name},CDate={Cdate.ToString()},Private={Private},UserId={UserId},SubscriberCount={SubscriberCount}"; } }
Essayez
"list":{ "0": { "id": "1", "name": "xxxxx xxxxxx xxxxxxx", "cdate": "2019-10-27 22:43:23", "private": "0", "userid": "1", "subscriber_count": 1 }, "1": { "id": "2", "name": "yyyyy yyyyy yyyyy", "cdate": "2019-10-27 22:44:03", "private": "0", "userid": "1", "subscriber_count": 0 }, "result_code": 1, "result_message": "Success: Something is returned", "result_output": "json" }
Cela ne résout pas le problème du PO. Le JSON provient d'un tiers.
@shan, n'emprunterait pas le chemin de manipulation JSON pour résoudre le problème. Le JSON reçu est fixe.
Votre JSON représente essentiellement un dictionnaire de paires string
- BasicList
, mélangé avec d'autres propriétés concernant le résultat global. Ce format rend le travail plus difficile. (Il aurait été préférable que les données du dictionnaire se trouvent dans un objet enfant dans le JSON.)
Le moyen le plus simple de gérer cette situation est de tirer parti de " Extension Data ".
Voici ce que vous devez faire:
Dictionary
dans votre classe BasicListResponse
et marquez-la avec l'attribut [JsonExtensionData]
. Cela capturera les données du dictionnaire lors de la désérialisation. list
en une List
au lieu d'un Dictionary
. (Je le renommerais également avec une capitalisation appropriée pour être cohérent avec vos autres propriétés.) OnDeserialized
privée comme indiqué ci-dessous pour remplir la List
à partir du dictionnaire d'extension à la fin du processus de désérialisation. Donc, votre classe BasicListResponse
devrait ressembler à ceci:
var result = JsonConvert.DeserializeObject<BasicListResponse>(json);
Il y a un autre petit problème que nous devons résoudre: dans votre classe BasicList
vous avez défini la propriété Private
comme bool
, mais dans le JSON, il s'agit d'une chaîne contenant un nombre. Cela entraînera l'échec de la désérialisation en raison de types incompatibles. Pour que cela fonctionne, vous pouvez soit changer Private
en une chaîne, puis gérer l'interprétation de la valeur ailleurs dans votre code, ou vous pouvez faire quelque chose comme ceci:
public class BasicList { ... [JsonProperty("private")] private string PrivateAsString { get; set; } [JsonIgnore] public bool Private { get { return PrivateAsString != "0"; } set { PrivateAsString = value ? "1" : "0"; } } ... }
Avec ces changements, vous pouvez désérialiser votre classe BasicListResponse
et tout devrait fonctionner correctement.
public class BasicListResponse : Result { public List<BasicList> List { get; set; } [JsonExtensionData] private Dictionary<string, JToken> Data { get; set; } [OnDeserialized] private void OnDeserialized(StreamingContext context) { List = Data?.OrderBy(kvp => kvp.Key) .Select(kvp => kvp.Value.ToObject<BasicList>()) .ToList(); } }
Démo de travail ici: https://dotnetfiddle.net/9MmSuG
Rodgers - je vais y aller
Rodgers, la solution a fonctionné. Merci pour l'aide. »[JsonExtensionData]` va être un excellent outil car je travaille avec beaucoup de JSON qui ne suivent pas une bonne structure.
Aucun problème; Je suis content que vous ayez trouvé la solution utile.
L'objet JSON ne contient pas de
liste
. Peut-être avez-vous besoin de cette question ?app.quicktype.io/#l=cs&r=json2csharp essayez ceci pour vous en sortir structure de classe correspondant à votre JSON
Est-ce que cela répond à votre question? Gestion des membres supplémentaires lors de la désérialisation avec Json.net
Peut-être que cela aide: dotnetfiddle.net/eSLWpe
Essayez de désérialiser directement dans
Dictionary
.@john - cette question était également utile. @ rahul-sharma - Votre solution fonctionnait mais j'ai opté pour @ brian-rodgers parce que j'avais tendance à convertir directement en
List
plutôt qu'endynamique