0

嗨我有一個問題,而反序列化可以有不同的數據類型(浮點數和浮點數組)的json文件。我有一個建議,使用自定義轉換器從Deserialize a json field with different data types without using Newtonsoft json but with System.Web.Script.Serialization.JavaScriptSerializer,它適用於一維數組。我目前正在給二維數組的jsons和這個轉換器不能處理相同。下面是我的JSON問題反序列化Json的多維數組字段使用System.Web.Script.Serialization.JavaScriptSerializer自定義轉換器

{ 
    "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] 
     ] 
     } 
    ] 
} 

片段凡默認即可有時原始的像

"default" : 3.56 

編輯:代碼用於自定義序列

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>(); 
    } 
} 

,並用它像

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

任何人都可以幫助我解決這個問題嗎?

+0

您能向我們展示您用於反序列化的代碼嗎?因爲這將有助於確定問題。 你也可以看看[反序列化成動態對象](https://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object)。 –

+0

添加了我用於float val和單維數組的自定義序列化的代碼。我需要做同樣的浮動值和多維數組(默認字段) – Sanga

+0

而不能使用動態對象,因爲使用system.web.helpers的限制:( – Sanga

回答

0

我通過使用字典而不是類對象來解決問題,以解析不同的數據類型字段並使用鍵值訪問各自的屬性。感謝大家的建議。