[英]Custom deserialize from json object string
我正在嘗試將此JSON反序列化為一個對象,但無法達到解決方案。
Json格式:
{"option1":
{"field1":"true","field2":"false"},
"option2":
{"field1":"true","field2":"false"}}
我有以下對象:
[Serializable]
public class genericFieldOptions
{
public string option { get; set; }
public string field { get; set; }
public bool value{ get; set; }
}
然后是“解串器”:
public class genericFieldsConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get
{
return new[] { typeof(genericFieldOptions) };
}
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
List<genericFieldOptions> p = new List<genericFieldOptions>();
foreach (var entry in dictionary.Keys)
{
try
{
Dictionary<string, Boolean> test = (Dictionary<string, Boolean>)dictionary[entry];//error
p.Add(new genericFieldOptions { key = entry, field1=test["field1"],field2=test["field2"] });
}
catch { }
}
return p;
}
電話:
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] { new genericFieldsConverter() });
var example= serializer.Deserialize<List<genericFieldOptions>>(json);
如何以Dictionary<string, Dictionary<string,boolean>>
的IDictionary<string, object>
訪問IDictionary<string, object>
? 還是只是不可能?
我究竟做錯了什么? 還有另一種簡單的方法嗎?
簡單的方法是正確制作代表序列化值的對象。 因此對於:
{"option1":
{"field1":"true","field2":"false"},
"option2":
{"field1":"true","field2":"false"}}
我會做:
public class Options
{
public Option Option1 { get; set; }
public Option Option2 { get; set; }
}
public class Option
{
public bool Field1 { get; set; }
public bool Field2 { get; set; }
}
對於初學者,一種更簡單的方法是使用http://json2csharp.com/ 。
如前所述,您可以使用Json.NET 。 如果您不想創建反序列化的類,則可以嘗試使用字典,也可以使用dynamic
。
const string json = "{\"option1\":{\"field1\":true,\"field2\":false}," +
"\"option2\":{\"field1\":true,\"field2\":false}}";
var result1 = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, bool>>>(json);
Console.WriteLine(result1["option2"]["field1"]);
dynamic result2 = JsonConvert.DeserializeObject(json);
Console.WriteLine(result2.option2.field1);
鑒於您已選擇使用javascriptserializer ,首先,您需要在List<genericFieldOptions>
而不是genericFieldOptions
級別進行轉換,因為序列化程序無法自動將JSON對象轉換為List<T>
。
其次,不是將嵌套的字典強制轉換為Dictionary<string, Boolean>
,而是需要強制轉換為IDictionary<string, object>
,然后使用JavaScriptSerializer.ConvertToType<bool>
將每個值反序列化為 bool
JavaScriptSerializer.ConvertToType<bool>
。 從而:
public class genericFieldsListConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get
{
return new[] { typeof(List<genericFieldOptions>) };
}
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
var query = from entry in dictionary
let subDictionary = entry.Value.AsJsonObject()
where subDictionary != null
from subEntry in subDictionary
select new genericFieldOptions { option = entry.Key, field = subEntry.Key, value = serializer.ConvertToType<bool>(subEntry.Value) };
return query.ToList();
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var list = (IList<genericFieldOptions>)obj;
if (list == null)
return null;
return list
.GroupBy(o => o.option)
.ToDictionary(g => g.Key, g => (object)g.ToDictionary(o => o.field, o => serializer.Serialize(o.value)));
}
}
public static class JavaScriptSerializerObjectExtensions
{
public static bool IsJsonObject(this object obj)
{
return obj is IDictionary<string, object>;
}
public static IDictionary<string, object> AsJsonObject(this object obj)
{
return obj as IDictionary<string, object>;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.