从json对象字符串自定义反序列化

时间:2016-03-06 00:34:31

标签: c# json serialization javascriptserializer

我试图将此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);

如何以IDictionary<string, object>的身份访问Dictionary<string, Dictionary<string,boolean>>?还是只是不可能?

我做错了什么?还有另一种简单的方法吗?

3 个答案:

答案 0 :(得分:0)

简单的方法是正确地创建表示序列化值的对象。所以:

{"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/

答案 1 :(得分:0)

如上所述,您可以使用Json.NET。如果您不想创建要反序列化的类,可以按照尝试使用字典,也可以使用create table Likes(ID1 number(5), ID2 number(5)); insert into Likes values(1689, 1709); insert into Likes values(1709, 1689); insert into Likes values(1782, 1709); insert into Likes values(1911, 1247); insert into Likes values(1247, 1468); insert into Likes values(1641, 1468); insert into Likes values(1316, 1304); insert into Likes values(1501, 1934); insert into Likes values(1934, 1501); insert into Likes values(1025, 1101);

dynamic

答案 2 :(得分:0)

鉴于您已选择使用,首先需要在List<genericFieldOptions>而不是genericFieldOptions级别进行转换,因为序列化程序无法将JSON对象转换为自动List<T>

其次,不是将嵌套字典强制转换为Dictionary<string, Boolean>,而是使用{{{}转换为IDictionary<string, object>然后反序列化每个值为bool 3}}。因此:

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