使用 newtonsoft 的 json 结构的序列化问题
serialization issue with json structure using newtonsoft
这是一个旧应用程序 (.Net 4.5)。
我正在按照此处的指南进行操作:https://weblog.west-wind.com/posts/2012/aug/30/using-jsonnet-for-dynamic-json-parsing
我的目标是找到一种方法来存储灵活的 json 结构,而不会将其绑定到静态结构。比如下面的TriggerJson,实际的Trigger字段是string类型,应该是json。 json 结构可以反映 ExpiryTriggerJson,或由 TriggerType 确定的其他结构。
我有以下结构:
public class TriggerJson
{
public string TriggerType { get; set; }
public string ConfiguredBy { get; set; }
public string Trigger { get; set; }
}
public class ExpiryTriggerJson
{
public string ActionType { get; set; }
public TriggerRecipient[] Recipients { get; set; }
}
public class TriggerRecipient
{
public string Id { get; set; }
public string Name { get; set; }
public bool IsTag { get; set; }
}
在下面的代码中,我创建了一个 TriggerJson 列表,这样每个元素的 Trigger 字段都是一个由 ExpiryTriggerJson 对象构成的 json 结构:
var tjList = new List<TriggerJson>();
var triggerJson = new TriggerJson();
triggerJson.TriggerType = TriggerJsonHelper.ExpiryTriggerType;
triggerJson.Trigger = JsonConvert.SerializeObject(new ExpiryTriggerJson
{
Recipients = taskRecipients,
ActionType = TriggerJsonHelper.ExpiryTriggerActionType_Task
});
triggerJson.ConfiguredBy = configuredBy;
tjList.Add(triggerJson);
fieldValue.TriggersJson = JsonConvert.SerializeObject(tjList);
这将创建以下结构,例如,其中触发器字段反映了一个序列化结构,该结构由于双重序列化而转义了双引号:
[{"TriggerType":"ExpiryTrigger","ConfiguredBy":"acd1ac353ac44e078aaef8ce6479a4c6","Trigger":"{\"ActionType\":\"CreateReminderTask\",\"Recipients\":[{\"Id\":\"70050a95-f31b-41b7-9b49-0688fa76dba5\",\"Name\":\"blah blah\",\"IsTag\":false}]}"}]
这对我在稍后读回时尝试反序列化这些数据造成了问题:
JArray jsonObj = JArray.Parse(triggersJson);
foreach (dynamic obj in jsonObj)
{
if (obj.TriggerType == ExpiryTriggerType)
{
ExpiryTriggerJson triggerData = obj.Trigger.ToObject<ExpiryTriggerJson>();
以上代码尝试解析回最初分配给TriggerJson元素的字段Trigger的ExpiryTriggerJson结构。这会在执行最后一行尝试转换为 ExpiryTriggerJson 时抛出运行时反序列化异常,我怀疑这是由于双重反序列化造成的。
我的问题是如何实现将 static/structural json 数据存储为字符串然后以嵌套方式解析它的目标?
这可能就是您想要的。
public dynamic Trigger {get;set;}
然后触发器将被解析为它在运行时接收到的任何类型。
这是一个旧应用程序 (.Net 4.5)。
我正在按照此处的指南进行操作:https://weblog.west-wind.com/posts/2012/aug/30/using-jsonnet-for-dynamic-json-parsing
我的目标是找到一种方法来存储灵活的 json 结构,而不会将其绑定到静态结构。比如下面的TriggerJson,实际的Trigger字段是string类型,应该是json。 json 结构可以反映 ExpiryTriggerJson,或由 TriggerType 确定的其他结构。
我有以下结构:
public class TriggerJson
{
public string TriggerType { get; set; }
public string ConfiguredBy { get; set; }
public string Trigger { get; set; }
}
public class ExpiryTriggerJson
{
public string ActionType { get; set; }
public TriggerRecipient[] Recipients { get; set; }
}
public class TriggerRecipient
{
public string Id { get; set; }
public string Name { get; set; }
public bool IsTag { get; set; }
}
在下面的代码中,我创建了一个 TriggerJson 列表,这样每个元素的 Trigger 字段都是一个由 ExpiryTriggerJson 对象构成的 json 结构:
var tjList = new List<TriggerJson>();
var triggerJson = new TriggerJson();
triggerJson.TriggerType = TriggerJsonHelper.ExpiryTriggerType;
triggerJson.Trigger = JsonConvert.SerializeObject(new ExpiryTriggerJson
{
Recipients = taskRecipients,
ActionType = TriggerJsonHelper.ExpiryTriggerActionType_Task
});
triggerJson.ConfiguredBy = configuredBy;
tjList.Add(triggerJson);
fieldValue.TriggersJson = JsonConvert.SerializeObject(tjList);
这将创建以下结构,例如,其中触发器字段反映了一个序列化结构,该结构由于双重序列化而转义了双引号:
[{"TriggerType":"ExpiryTrigger","ConfiguredBy":"acd1ac353ac44e078aaef8ce6479a4c6","Trigger":"{\"ActionType\":\"CreateReminderTask\",\"Recipients\":[{\"Id\":\"70050a95-f31b-41b7-9b49-0688fa76dba5\",\"Name\":\"blah blah\",\"IsTag\":false}]}"}]
这对我在稍后读回时尝试反序列化这些数据造成了问题:
JArray jsonObj = JArray.Parse(triggersJson);
foreach (dynamic obj in jsonObj)
{
if (obj.TriggerType == ExpiryTriggerType)
{
ExpiryTriggerJson triggerData = obj.Trigger.ToObject<ExpiryTriggerJson>();
以上代码尝试解析回最初分配给TriggerJson元素的字段Trigger的ExpiryTriggerJson结构。这会在执行最后一行尝试转换为 ExpiryTriggerJson 时抛出运行时反序列化异常,我怀疑这是由于双重反序列化造成的。
我的问题是如何实现将 static/structural json 数据存储为字符串然后以嵌套方式解析它的目标?
这可能就是您想要的。
public dynamic Trigger {get;set;}
然后触发器将被解析为它在运行时接收到的任何类型。