2016-11-05 5 views
3

J'ai une classepersonnalisé en utilisant Désérialisation Json.NET

public class Order 
{ 
    public int Id { get; set; } 
    public string ShippingMethod { get; set; } 
} 

et je veux désérialiser des données JSON ci-dessous dans la classe/objet ci-dessus

string json = @"{ 
    'Id': 1, 
    'ShippingMethod': { 
    'Code': 'external_DHLExpressWorldwide', 
    'Description': 'DHL ILS Express Worldwide' 
    } 
}"; 

Mon idée est que ShippingMethod dans JSON est un objet, mais je veux juste arriver à ShippingMethod.Code (en JSON) qui passera en ShippingMethod comme string en classe Order lors de la désérialisation.

comment puis-je atteindre cet objectif en utilisant Json.NET?

Je crois que je peux l'accomlir en utilisant CustomJsonConverter. Mais je suis confus. L'exemple dans les docs juste pour WriteJson, mais pas ReadJson.

+0

Donc 'Code' et' Description' sont dans 'ShippingMethod'? Comment sont sérialisés? – Tinwor

+0

Vous avez juste besoin d'avoir "Id" et "Code" au même niveau? – CodeNotFound

+0

Ouais, c'est mon problème et ce que je veux accomplir – Habibillah

Répondre

7

I Il suffit de résoudre mon problème en utilisant JsonConverter comme je l'ai mentionné ci-dessus dans ma question. Ci-dessous mon code complet:

public class Order 
{ 
    public int Id { get; set; } 

    [JsonConverter(typeof(ShippingMethodConverter))] 
    public string ShippingMethod { get; set; } 
} 

public class ShippingMethodConverter : JsonConverter 
{ 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException("Not implemented yet"); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
     { 
      return string.Empty; 
     } 
     else if (reader.TokenType == JsonToken.String) 
     { 
      return serializer.Deserialize(reader, objectType); 
     } 
     else 
     { 
      JObject obj = JObject.Load(reader); 
      if (obj["Code"] != null) 
       return obj["Code"].ToString(); 
      else 
       return serializer.Deserialize(reader, objectType); 
     } 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return false; 
    } 
} 
2

Vous pouvez utiliser JsonProperty et JsonIgnore attributs pour diriger le processus de désérialisation ... Donc, votre modèle peut être:

public class Order 
{ 
    public int Id { get; set; } 

    [JsonIgnore] 
    public string ShippingMethod 
    { 
     get 
     { 
      return (string)TempShippingMethod?["Code"]; 
     } 
    } 

    [JsonProperty("ShippingMethod")] 
    private JObject TempShippingMethod { set; get; } 
} 

var res = JsonConvert.DeserializeObject<Order>(json); 
+0

Ouais, c'est juste un tout petit bidouillage. Je n'aime pas de cette façon, mais je l'ai upvote :) comme mon respect pour votre réponse – Habibillah

+0

@Habibillah Je n'ai pas aimé votre réponse aussi, trop lourde pour une chose simple, Mais comme mon respect à votre avis, j'ai posté un simplifié version de ma réponse .. –

+0

Pas de soucis :). La question est simple penser, mais mon vrai mot, avec beaucoup de propriété et mauvais schéma json, ça vaut vraiment la peine. Exemple. En enregistrant une commande, vous devez passer une chaîne, mais pour obtenir les détails de la commande, vous avez un objet. Et beaucoup plus – Habibillah

4
dynamic o = JsonConvert.DeserializeObject(json); 
var oder = new Order 
{ 
    Id = o.Id, 
    ShippingMethod = o.ShippingMethod.Code 
}; 

Désérialise l'objet comme dynamique et puis remplissez le Order objet en accédant aux propriétés de l'objet dynamique

+0

+1 pour celui-ci. Je pense que c'est la meilleure manière propre sans pollution d'attribut et nouvelle création de classe :) – CodeNotFound

+0

Merci pour votre réponse, mais il ne convient pas s'il y a beaucoup d'autres propriétés – Habibillah

+0

Vous n'avez pas dit qu'il y a plus de propriétés à gérer. Pour résoudre cela, vous pouvez ajouter une méthode d'extension cette carte une fois et vous pouvez l'utiliser où vous voulez. Mais aussi votre solution semble ok, juste pour beaucoup de ligne de code fortwo propriétés (à mon avis) – Tinwor