C# 如何在动态解析JSON后确定中是否存在节点
我有下面一段代码,它从事件中心读取传入消息并将其存储在blob存储中C# 如何在动态解析JSON后确定中是否存在节点,c#,json,json.net,C#,Json,Json.net,我有下面一段代码,它从事件中心读取传入消息并将其存储在blob存储中 dynamic msg = JObject.Parse(myEventHubMessage); WriteToBlob(msg, enqueuedTimeUtc, myEventHubMessage, binder, log); 以下是我收到的一些JSON示例: { "deviceId": "ATT", "product": "testprod", "data": { "001": 1, "002
dynamic msg = JObject.Parse(myEventHubMessage);
WriteToBlob(msg, enqueuedTimeUtc, myEventHubMessage, binder, log);
以下是我收到的一些JSON示例:
{
"deviceId": "ATT",
"product": "testprod",
"data": {
"001": 1,
"002": 3.1,
"003": {
"lat": 0,
"lng": 0
},
"000": -80
},
"ts": "2020-01-27T19:29:34Z"
}
现在,代替JSON中的“数据”节点,有时设备发送名为“data_in”的节点。ts字段有时可以位于节点中的数据或数据_的内部或外部,也可以命名为timestamp。如何有效地确定节点是否存在
我想做这样的事情:
if (msg.data_in.ts != null)
{
}
在所有情况下我都会这么做。有没有办法更好地实现这一点?另外,如果我检查msg.data\u in.ts if data\u in节点不存在,if条件将失败。您的问题是您已将
作业对象
向上转换为动态
。这使得事情变得困难,原因如下:
- 您失去了所有编译时代码正确性检查
- 您无法方便地访问其自身的方法和属性(与动态提供的JSON属性相反)
由于
实现了诸如JObject
之类的接口,将其保留为类型化对象将使检查、添加和删除select JSON属性的工作更加容易IDictionary
JObject
更容易,请首先介绍以下扩展方法以方便使用:
public static class JsonExtensions
{
public static JProperty Rename(this JProperty old, string newName)
{
if (old == null)
throw new ArgumentNullException();
var value = old.Value;
old.Value = null; // Prevent cloning of the value by nulling out the old property's value.
var @new = new JProperty(newName, value);
old.Replace(@new); // By using Replace we preserve the order of properties in the JObject.
return @new;
}
public static JProperty MoveTo(this JToken token, JObject newParent)
{
if (newParent == null || token == null)
throw new ArgumentNullException();
var toMove = (token as JProperty ?? token.Parent as JProperty);
if (toMove == null)
throw new ArgumentException("Incoming token does not belong to an object.");
if (toMove.Parent == newParent)
return toMove;
toMove.Remove();
newParent.Add(toMove);
return toMove;
}
}
现在,您可以按如下方式规范消息:
var msg = JObject.Parse(myEventHubMessage);
msg.Property("data_in")?.Rename("data"); // Normalize the name "data_in" to be "data".
msg["data"]?["ts"]?.MoveTo(msg); // Normalize the position of the "ts" property, it should belong to the root object
msg["data"]?["timestamp"]?.MoveTo(msg); // Normalize the position of the "timestamp" property, it should belong to the root object
msg.Property("timestamp")?.Rename("ts"); // And normalize the name of the "timestamp" property, it should be "ts".
演示小提琴
var msg = JObject.Parse(myEventHubMessage);
msg.Property("data_in")?.Rename("data"); // Normalize the name "data_in" to be "data".
msg["data"]?["ts"]?.MoveTo(msg); // Normalize the position of the "ts" property, it should belong to the root object
msg["data"]?["timestamp"]?.MoveTo(msg); // Normalize the position of the "timestamp" property, it should belong to the root object
msg.Property("timestamp")?.Rename("ts"); // And normalize the name of the "timestamp" property, it should be "ts".