将json反序列化为3个属性中的对象

时间:2016-08-29 19:14:22

标签: c# json json.net deserialization

假设我有一些有3个对象和值的json

{
    "SomeProperty": "42",
    "Foo": "bar",
    "Name001": "ABC_1",
    "Type001": "D",
    "Confidence001": "100",
    ...
    "Name00N": "ABC_N",
    "Type00N": "D",
    "Confidence00N": "50",

}

我如何使用转换器/映射器将这3个对象分组到一个POCO中?

public class DeserializedJsonClass
{
    public long SomeProperty {get;set;}
    public string Foo {get;set;}
    public EvaluationStat[] Evaluations {get;set;}
}
public class EvaluationStat
{
    public string Name {get;set;}
    public char Type {get;set;}
    public int Confidence {get;set;}
}

我已经了解了牛顿软件的映射,我使用转换器将Y / N转换为bool,将某些xml转换为XDocument,但我无法弄清楚如何映射将这三个对象合二为一。

3 个答案:

答案 0 :(得分:2)

解决问题的一种方法:

public class DeserializedJsonClass
{
    public long SomeProperty { get; set; }
    public string Foo { get; set; }
    public IEnumerable<EvaluationStat> Evaluations { get; set; }
}

public class EvaluationStat
{
    public string Name { get; set; }
    public char Type { get; set; }
    public int Confidence { get; set; }
}


// ...

private static DeserializedJsonClass Deserialize(string json)
{
    // using Newtonsoft.Json
    dynamic deserialized = JsonConvert.DeserializeObject(json);
    DeserializedJsonClass result = new DeserializedJsonClass();
    result.SomeProperty = deserialized.SomeProperty;
    result.Foo = deserialized.Foo;
    result.Evaluations = FetchEvaluations(deserialized);
    return result;
}

private static IEnumerable<EvaluationStat> FetchEvaluations(dynamic json)
{
    ICollection<string> names = new List<string>();
    ICollection<char> types = new List<char>();
    ICollection<int> confidences = new List<int>();

    foreach (var prop in json)
    {
        if (prop.Name.StartsWith("Name"))
           names.Add((string)prop.Value.Value);
        else if (prop.Name.StartsWith("Type"))
           types.Add(Convert.ToChar((string)prop.Value.Value));
        else if (prop.Name.StartsWith("Confidence"))
           confidences.Add(Convert.ToInt32((string)prop.Value.Value));
    }

    return names.Zip(types, (n, t) => new { Name = n, Type = t })
                .Zip(confidences, (l, c) => new { Name = l.Name, Type = l.Type, Confidence = c })
                .Select(t => new EvaluationStat()
    {
        Name = t.Name,
        Type = t.Type,
        Confidence = t.Confidence
    });
}

答案 1 :(得分:1)

如果您能够更改源数据,则可以将此JSON反序列化为您提议的类。

[   
    {   
        "Name": "ABC_1", 
        "Type": "D",
        "Confidence": "100"
    },
    ...
    {   
        "Name": "ABC_N", 
        "Type": "D",
        "Confidence": "50"
    }
]

答案 2 :(得分:1)

自定义JsonConvert是另一种方法

public class EvaluationStatJsonConverter : JsonConverter
    {
        public override bool CanConvert( Type objectType ) { return objectType == typeof( DeserializedJsonClass ); }

        public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
        {
            var jsonObject = JObject.Load( reader );
            var properties = typeof( EvaluationStat ).GetProperties();

            var deserializedJsonClass = new DeserializedJsonClass
            {
                Evaluations = new EvaluationStat[jsonObject.Count / properties.Length]
            };

            for( var i = 1; i <= jsonObject.Count / properties.Length; i++ )
            {
                deserializedJsonClass.Evaluations[ i - 1 ] = new EvaluationStat();
                foreach( var field in properties )
                {
                    field.SetValue( deserializedJsonClass.Evaluations[ i - 1 ],
                                    jsonObject[ $"{field.Name}{i:000}" ].ToObject( field.PropertyType ) );
                }
            }
            return deserializedJsonClass;
        }

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

然后你想要使用它,你可以做到这一点

var jss = new JsonSerializerSettings();
            jss.Converters.Add( new EvaluationStatJsonConverter() );
            var result =
                JsonConvert.DeserializeObject< DeserializedJsonClass >(
                                                                       "your json content" ),
                                                                       jss );

我同意其他评论,这是一个非常好的解决方案。