【发布时间】:2018-11-29 14:19:39
【问题描述】:
我正在尝试在 C# 应用程序中读取 json 片段。
在片段中,有一个数组可以包含简单的字符串或复杂的对象。这是因为包含的对象只有一个强制字符串,其他字段是可选的。因此,为了简化 json,数组可以包含字符串(= 默认参数)或复杂对象。
这是一个示例 json:
{
"Config1": [
"Simple string 1",
"Simple string 2",
{
"Data": "Complex object",
"OptionalField": "some option",
"AnotherOption": 42
}
],
"Config3": [
"Simple string 3",
"Simple string 4",
{
"Data": "Complex object 2",
"OptionalField": "some option",
"AnotherOption": 12
}
]
}
对应的C#模型:
public class Config : Dictionary<string, ConfigItem[]>
{
}
public class ConfigItem
{
public ConfigItem()
{
}
public ConfigItem(string data)
{
this.Data = data;
}
public string Data { get; set; }
public string OptionalField { get; set; }
public int AnotherOption { get; set; }
}
在我的示例中,只有 Data 字段是强制性的。提供字符串时,必须调用具有单个字符串参数的构造函数。当提供复杂的 json 对象时,必须运行标准的反序列化。
例如这两个json片段是等价的(在数组内):
"Config4": [
"This is a string",
{
"Data": "This is a string",
"OptionalField": null,
"AnotherOption": 0
}
]
如何达到我的目标?
现在,我尝试实现一个自定义转换器:
[JsonConverter(typeof(StringToComplexConverter))]
public class ConfigItem
{
// Properties omiited
}
public class StringToComplexConverter : JsonConverter<ConfigItem>
{
public override bool CanWrite => false;
public override ConfigItem ReadJson(JsonReader reader, Type objectType, ConfigItem existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if(reader.TokenType == JsonToken.String)
{
var ctor = objectType.GetConstructor(new[] { typeof(string) });
return (ConfigItem)ctor.Invoke(new[] { (string)reader.Value });
}
else
{
// What to put in the else ?
}
}
public override void WriteJson(JsonWriter writer, ConfigItem value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
这实际上适用于字符串。但是,我没有找到在else 语句中添加的内容。有没有办法从 ReadJson 方法转发到标准反序列化?
如果我在 else 语句中输入return serializer.Deserialize<ConfigItem>(reader);,它会以无限循环结束。
也试过return serializer.Deserialize<JObject>(reader).ToObject<ConfigItem>();,没有成功。
【问题讨论】:
-
我认为你需要继承非泛型
JsonConverter。 -
@Amy:不确定你的意思。使用非泛型转换器,我仍然得到一个无限循环。
-
实现通用转换器意味着您只能返回该类型的对象。你不能打电话给
serializer.Deserialize...,因为它只使用你的转换器,但我有理由确定你需要实现非通用转换器。 -
见this question。这对您反序列化对象有帮助吗?
-
另见this question。这个可能是骗子。我不知道。今天早上我还没有喝咖啡:(