0

Salut j'ai eu un problème lors de la désérialisation un fichier JSON qui peut avoir différents types de données (float et flotter tableau). J'ai une suggestion pour utiliser le convertisseur personnalisé de Deserialize a json field with different data types without using Newtonsoft json but with System.Web.Script.Serialization.JavaScriptSerializer et cela fonctionne très bien pour un tableau à une dimension. Je reçois actuellement des jsons avec un réseau bidimensionnel et ce convertisseur ne pourrait pas supporter la même chose. Ci-dessous un extrait de mon JSONProblème lors de la désérialisation champ tableau Multidimensional de JSON en utilisant le convertisseur System.Web.Script.Serialization.JavaScriptSerializer personnalisé

{ 
    "name"   : "foo", 
    "value"  : 457, 
    "comment"  : "bla bla bla", 
    "data" : [ 
     {   
     "name"  : "bar", 
     "max"  : 200, 
     "default" : [ 
      [7,4],[2,2],[7,4],[1,1],[2,3],[3,1],[7,9] 
     ] 
     } 
    ] 
} 

Si la valeur par défaut peut être parfois primitive comme

"default" : 3.56 

Edit: code utilisé pour la sérialisation personnalisé

class RootObjectConverter : CustomPropertiesConverter<RootObject> 
{ 
    const string ValuesName = "values"; 

    protected override IEnumerable<string> CustomProperties 
    { 
     get { return new[] { ValuesName }; } 
    } 

    protected override void DeserializeCustomProperties(Dictionary<string, object> customDictionary, RootObject obj, JavaScriptSerializer serializer) 
    { 
     object itemCost; 
     if (customDictionary.TryGetValue(ValuesName, out itemCost) && itemCost != null) 
      obj.Values = serializer.FromSingleOrArray<float>(itemCost).ToArray(); 
    } 

    protected override void SerializeCustomProperties(RootObject obj, Dictionary<string, object> dict, JavaScriptSerializer serializer) 
    { 
     obj.Values.ToSingleOrArray(dict, ValuesName); 
    } 
} 

public abstract class CustomPropertiesConverter<T> : JavaScriptConverter 
{ 
    protected abstract IEnumerable<string> CustomProperties { get; } 

    protected abstract void DeserializeCustomProperties(Dictionary<string, object> customDictionary, T obj, JavaScriptSerializer serializer); 

    protected abstract void SerializeCustomProperties(T obj, Dictionary<string, object> dict, JavaScriptSerializer serializer); 

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) 
    { 
     // Detach custom properties 
     var customDictionary = new Dictionary<string, object>(); 
     foreach (var key in CustomProperties) 
     { 
      object value; 
      if (dictionary.TryRemoveInvariant(key, out value)) 
       customDictionary.Add(key, value); 
     } 

     // Deserialize and populate all members other than "values" 
     var obj = new JavaScriptSerializer().ConvertToType<T>(dictionary); 

     // Populate custom properties 
     DeserializeCustomProperties(customDictionary, obj, serializer); 

     return obj; 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     // Generate a default serialization. Is there an easier way to do this? 
     var defaultSerializer = new JavaScriptSerializer(); 
     var dict = defaultSerializer.Deserialize<Dictionary<string, object>>(defaultSerializer.Serialize(obj)); 

     // Remove default serializations of custom properties, if present 
     foreach (var key in CustomProperties) 
     { 
      dict.RemoveInvariant(key); 
     } 

     // Add custom properties 
     SerializeCustomProperties((T)obj, dict, serializer); 

     return dict; 
    } 

    public override IEnumerable<Type> SupportedTypes 
    { 
     get { return new[] { typeof(T) }; } 
    } 
} 

public static class JavaScriptSerializerObjectExtensions 
{ 
    public static void ReplaceInvariant<T>(this IDictionary<string, T> dictionary, string key, T value) 
    { 
     RemoveInvariant(dictionary, key); 
     dictionary.Add(key, value); 
    } 

    public static bool TryRemoveInvariant<T>(this IDictionary<string, T> dictionary, string key, out T value) 
    { 
     if (dictionary == null) 
      throw new ArgumentNullException(); 
     var keys = dictionary.Keys.Where(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase)).ToArray(); 
     if (keys.Length == 0) 
     { 
      value = default(T); 
      return false; 
     } 
     else if (keys.Length == 1) 
     { 
      value = dictionary[keys[0]]; 
      dictionary.Remove(keys[0]); 
      return true; 
     } 
     else 
     { 
      throw new ArgumentException(string.Format("Duplicate keys found: {0}", String.Join(",", keys))); 
     } 
    } 

    public static void RemoveInvariant<T>(this IDictionary<string, T> dictionary, string key) 
    { 
     if (dictionary == null) 
      throw new ArgumentNullException(); 
     foreach (var actualKey in dictionary.Keys.Where(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase)).ToArray()) 
      dictionary.Remove(actualKey); 
    } 

    public static void ToSingleOrArray<T>(this ICollection<T> list, IDictionary<string, object> dictionary, string key) 
    { 
     if (dictionary == null) 
      throw new ArgumentNullException(); 
     if (list == null || list.Count == 0) 
      dictionary.RemoveInvariant(key); 
     else if (list.Count == 1) 
      dictionary.ReplaceInvariant(key, list.First()); 
     else 
      dictionary.ReplaceInvariant(key, list.ToArray()); 
    } 

    public static List<T> FromSingleOrArray<T>(this JavaScriptSerializer serializer, object value) 
    { 
     if (value == null) 
      return null; 
     if (value.IsJsonArray()) 
     { 
      return value.AsJsonArray().Select(i => serializer.ConvertToType<T>(i)).ToList(); 
     } 
     else 
     { 
      return new List<T> { serializer.ConvertToType<T>(value) }; 
     } 
    } 

    public static bool IsJsonArray(this object obj) 
    { 
     if (obj is string || obj is IDictionary) 
      return false; 
     return obj is IEnumerable; 
    } 

    public static IEnumerable<object> AsJsonArray(this object obj) 
    { 
     return (obj as IEnumerable).Cast<object>(); 
    } 
} 

et utilisé comme

var serializer = new JavaScriptSerializer(); 
serializer.RegisterConverters(new[] { new RootObjectConverter() }); 
var root = serializer.Deserialize<RootObject>(json); 

Quelqu'un peut-il m'aider sur la façon de procéder à ce sujet?

+0

Pourriez-vous nous montrer le code que vous utilisez pour désérialiser? Parce que cela va aider à déterminer le problème. Vous pouvez également regarder dans [désérialisation dans un objet dynamique] (https://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object). –

+0

Ajout du code que j'ai utilisé pour la sérialisation personnalisée pour float val et array unidimensionnel. Je dois faire la même chose pour valeur flottante et tableau multi dimensions (le champ par défaut) – Sanga

+0

et l'utilisation de dévers objet dynamique en raison de la restriction sur l'utilisation system.web.helpers :( – Sanga

Répondre

0

je résolu le problème en utilisant un dictionnaire au lieu d'un objet de classe pour analyser différents champs de type de données et l'accès à la propriété respective à la valeur. Merci à tous pour vos suggestions.