我制作了一个简单的自定义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
}
我已经设置了json格式化程序设置:
jsonOutputFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
jsonInputFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
当我通过Page
输出Web API
对象时,我得到的JSON结构与上面的结构完全相同。当我发送回确切的JSON数据时,我希望它可以很好地映射回Page
列表属性中具有正确类型的Field
对象。
但所有Fields
都映射到其基类Field
,而不是$type
中定义的类型。
所以目前JSON格式化器非常适合输出。它显示了所有$type
个。但输入映射并没有真正映射回其特定类型。
答案 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