JsonConvert转换为自定义对象

时间:2015-05-25 11:42:00

标签: c# json.net

我制作了一个简单的自定义JsonConvert课程。现在我正在尝试将JSON数据转换为自定义类,如下所示:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    //JObject jo = JObject.Load(reader);
    MyItem instance = serializer.Deserialize<MyItem>(reader);

    // want to do more thing here...
}

每次执行Deserialize<>()方法时,它都会重新进入ReadJson方法,从而使我处于永无止境的循环中。

如何将JSON数据转换为我的自定义对象,而不会以永无止境的循环结束?

更新

我收到的JSON是通用的。我需要自定义转换器将其映射到正确的类型。 JSON看起来像这样:

{
    /* Base obj properties, should be mapped to Page.cs */
    "$type": "App.Models.Page, App",
    "title": "Page title",
    "technicalName": "some_key",
    "fields": [

        /* Should be mapped to InputField.cs */
        {
            "$type": "App.Models.InputField, App",
            "type": "input",
            "typeTitle": "Input",
            "title": "Input",
            "technicalName": "input",
            "inputType": "text",
            "defaultValue": "Input default value"
        },

        /* Should be mapped to TextareaField.cs */
        {
            "$type": "App.Models.TextareaField, App",
            "type": "textarea",
            "typeTitle": "Textarea",
            "title": "Textarea",
            "technicalName": "textarea",
            "defaultValue": "default textarea value"
        }
    ]
}

简而言之,我的类文件如下所示:

class Page
{
    public string Title {get;set;}
    public string TechnicalName {get;set;}

    public List<Field> Fields {get;set;} // Note the base class "Field"
}

class InputField : Field // Field has base properties
{
 // InputField has its own properties
}

class TextareaField : Field // Field has base properties
{
 // TextareaField has its own properties
}

TypeNameHandling

我已经设置了json格式化程序设置:

jsonOutputFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
jsonInputFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;

当我通过Page输出Web API对象时,我得到的JSON结构与上面的结构完全相同。当我发送回确切的JSON数据时,我希望它可以很好地映射回Page列表属性中具有正确类型的Field对象。

但所有Fields都映射到其基类Field,而不是$type中定义的类型。

所以目前JSON格式化器非常适合输出。它显示了所有$type个。但输入映射并没有真正映射回其特定类型。

2 个答案:

答案 0 :(得分:1)

public static class ConvertToJson
{ 
    public static T Deserialize<T>(string json)
    {
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            return (T)serializer.ReadObject(ms);
        }
    }
}

答案 1 :(得分:1)

鉴于您在Web API端使用Json.NET,您不需要自定义JsonConverter。您可以明确告诉JsonFormatter(内部使用Json.NET)使用TypeNameHandling.All。这样,它就可以确切地知道在给定IEnumerable<BaseType>的情况下要反序列化的类型。有关详细信息,请参阅how to deserialize JSON into IEnumerable<BaseType> with Newtonsoft JSON.NET