简体   繁体   English

在json反序列化过程中确定对象“类型”

[英]Determining object “type” during json deserialization

While trying to de-serialize a complex JSON object (JIRA issue) into an object containing a dictionary of type string-Field I've hit a bit of a bump. 在尝试将复杂的JSON对象反序列化为一个包含string-Field类型的字典的对象时,我遇到了一些麻烦。

While I can de-serialize various pre-determined object types (standard), I'm having a bit of a harder time with the custom fields, which could be of various types (they all begin with customfield_ followed by a set of numbers). 虽然我可以反序列化各种预定的对象类型(标准),但是自定义字段却有点麻烦,自定义字段可能是各种类型(它们都以customfield_开头,后跟一组数字) 。

The custom fields can be floats, strings, booleans, objects and arrays of objects. 自定义字段可以是浮点数,字符串,布尔值,对象和对象数组。 The latter of these is causing me issues since I can't seem to determine what the object is before I de-serialize it. 后者导致我出现问题,因为在反序列化之前似乎无法确定对象是什么。

I've searched for a way to perhaps "peek" at the data in the object before de-serializing as one of the fields contains information specific to it's type. 我搜索了一种方法,可以在反序列化之前“偷看”对象中的数据,因为其中一个字段包含特定于其类型的信息。 This is all so I can determine the type of the object and tell Json.Net what to de-serialize it as. 这就是全部,因此我可以确定对象的类型,并告诉Json.Net将其反序列化为什么内容。

I've considered parsing the JSON string before serialization to get the information, or maybe just when hitting this particular case, but maybe there is a better way? 我已经考虑过在序列化之前解析JSON字符串以获取信息,或者可能只是在遇到这种特殊情况时进行解析,但是也许有更好的方法吗?

Thanks in advance for any advice on this. 在此先感谢您的任何建议。

You can deserialize to an object with Json.Net. 您可以使用Json.Net反序列化为对象。 Here's a quick and dirty example: 这是一个快速而肮脏的例子:

using System;
using Newtonsoft.Json;

namespace Sandbox
{
class Program
{
    private static void Main(string[] args)
    {
       var nestDto = new Dto
        {
            customfield_1 = 20,
            customfield_2 = "Test2"
        };

        var dto = new Dto
        {
            customfield_1 = 10,
            customfield_3 = new[] { nestDto },
            customfield_2 = "Test"
        };

        var jsonString = JsonConvert.SerializeObject(dto);
        Console.WriteLine(jsonString);

        var fromJsonString = JsonConvert.DeserializeObject<Dto>(jsonString);

        Console.WriteLine(fromJsonString.customfield_3[0].customfield_2); //Outputs Test2
        Console.ReadKey();
    }
}

class Dto
{
    public int customfield_1 { get; set; }
    public string customfield_2 { get; set; }
    public Dto[] customfield_3 { get; set; }
}
}

Instead of peaking, you can deserialize as the same type as JSON.net uses for ExtensionData explicitly. 您可以使用与JSON.net显式用于ExtensionData相同的类型来反序列化,而不必达到峰值。 For example: 例如:

if (reader.TokenType == JsonToken.StartArray)
{
    var values = serializer.Deserialize<List<Dictionary<string, JToken>>>(reader);
    objectContainer = ClassifyAndReturn(values); 
}

private ObjectType ClassifyAndReturn(List<Dictionary<string, JToken>> values)
{
    if (values.First().ContainsKey("self"))
    {
        string self = values.First()["self"].Value<string>();
        if (self.Contains("customFieldOption"))
        //... Then go into a series of if else cases to determine the object. 

The representation of the objects are given as a Dictionary of string to JToken, which can then easily be checked and assigned manually or in some cases automatically deserialized (in the case one of the fields is another object). 对象的表示形式是JToken的字符串字典,可以方便地对其进行检查和手动分配,或者在某些情况下可以自动反序列化(在其中一个字段是另一个对象的情况下)。

Here is what an object constructor could look like: 这是对象构造函数的外观:

internal myobject(Dictionary<string, JToken> source)
{
    Self = source["self"].Value<string>();
    Id = source["id"].Value<string>();
    Value = source["value"].Value<string>();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM