mirror of
				https://gitee.com/ThingsGateway/ThingsGateway.git
				synced 2025-10-31 15:43:59 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			221 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | ||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
 | ||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有
 | ||
| //  源代码使用协议遵循本仓库的开源协议及附加协议
 | ||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
 | ||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
 | ||
| //  使用文档:https://thingsgateway.cn/
 | ||
| //  QQ群:605534569
 | ||
| //------------------------------------------------------------------------------
 | ||
| 
 | ||
| using Newtonsoft.Json.Linq;
 | ||
| 
 | ||
| namespace ThingsGateway.NewLife.Json.Extension;
 | ||
| 
 | ||
| /// <summary>
 | ||
| /// JTokenUtil
 | ||
| /// </summary>
 | ||
| public static class JTokenUtil
 | ||
| {
 | ||
|     /// <summary>
 | ||
|     /// 根据字符串解析对应JToken<br></br>
 | ||
|     /// 字符串可以不包含转义双引号,如果解析失败会直接转成String类型的JValue
 | ||
|     /// true/false可忽略大小写
 | ||
|     /// </summary>
 | ||
|     /// <param name="item"></param>
 | ||
|     /// <returns></returns>
 | ||
|     public static JToken GetJTokenFromString(this string item)
 | ||
|     {
 | ||
|         try
 | ||
|         {
 | ||
|             if (item.IsNullOrEmpty())
 | ||
|                 return JValue.CreateNull();
 | ||
| 
 | ||
|             if (bool.TryParse(item, out bool parseBool))
 | ||
|                 return new JValue(parseBool);
 | ||
| 
 | ||
|             // 尝试解析字符串为 JToken 对象
 | ||
|             return JToken.Parse(item);
 | ||
|         }
 | ||
|         catch
 | ||
|         {
 | ||
|             // 解析失败时,将其转为 String 类型的 JValue
 | ||
|             return new JValue(item);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /// <summary>
 | ||
|     /// 根据JToken获取Object类型值<br></br>
 | ||
|     /// 对应返回 对象字典 或 类型数组 或 类型值
 | ||
|     /// </summary>
 | ||
|     public static object? GetObjectFromJToken(this JToken token)
 | ||
|     {
 | ||
|         if (token == null)
 | ||
|             return null;
 | ||
| 
 | ||
|         switch (token.Type)
 | ||
|         {
 | ||
|             case JTokenType.Object:
 | ||
|                 var obj = new Dictionary<string, object>();
 | ||
|                 foreach (var prop in (JObject)token)
 | ||
|                     obj[prop.Key] = GetObjectFromJToken(prop.Value);
 | ||
|                 return obj;
 | ||
| 
 | ||
|             case JTokenType.Array:
 | ||
|                 var array = (JArray)token;
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.Integer))
 | ||
|                     return array.Select(x => x.Value<long>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.Float))
 | ||
|                     return array.Select(x => x.Value<double>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.String))
 | ||
|                     return array.Select(x => x.Value<string>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.Boolean))
 | ||
|                     return array.Select(x => x.Value<bool>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.Date))
 | ||
|                     return array.Select(x => x.Value<DateTime>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.TimeSpan))
 | ||
|                     return array.Select(x => x.Value<TimeSpan>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.Guid))
 | ||
|                     return array.Select(x => x.Value<Guid>()).ToArray();
 | ||
| 
 | ||
|                 if (array.All(x => x.Type == JTokenType.Uri))
 | ||
|                     return array.Select(x => x.Value<Uri>()).ToArray();
 | ||
| 
 | ||
|                 // 否则递归
 | ||
|                 return array.Select(x => GetObjectFromJToken(x)).ToArray();
 | ||
| 
 | ||
|             case JTokenType.Integer:
 | ||
|                 return token.ToObject<long>();
 | ||
| 
 | ||
|             case JTokenType.Float:
 | ||
|                 return token.ToObject<double>();
 | ||
| 
 | ||
|             case JTokenType.String:
 | ||
|                 return token.ToObject<string>();
 | ||
| 
 | ||
|             case JTokenType.Boolean:
 | ||
|                 return token.ToObject<bool>();
 | ||
| 
 | ||
|             case JTokenType.Null:
 | ||
|             case JTokenType.Undefined:
 | ||
|                 return null;
 | ||
| 
 | ||
|             case JTokenType.Date:
 | ||
|                 return token.ToObject<DateTime>();
 | ||
| 
 | ||
|             case JTokenType.TimeSpan:
 | ||
|                 return token.ToObject<TimeSpan>();
 | ||
| 
 | ||
|             case JTokenType.Guid:
 | ||
|                 return token.ToObject<Guid>();
 | ||
| 
 | ||
|             case JTokenType.Uri:
 | ||
|                 return token.ToObject<Uri>();
 | ||
| 
 | ||
|             case JTokenType.Bytes:
 | ||
|                 return token.ToObject<byte[]>();
 | ||
| 
 | ||
|             case JTokenType.Comment:
 | ||
|             case JTokenType.Raw:
 | ||
|             case JTokenType.Property:
 | ||
|             case JTokenType.Constructor:
 | ||
|             default:
 | ||
|                 return token.ToString();
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     /// <summary>
 | ||
|     /// 把任意对象转换为 JToken。
 | ||
|     /// 支持 JsonElement、JToken、本地 CLR 类型。
 | ||
|     /// </summary>
 | ||
|     public static JToken GetJTokenFromObj(this object value)
 | ||
|     {
 | ||
|         if (value == null)
 | ||
|             return JValue.CreateNull();
 | ||
| 
 | ||
|         switch (value)
 | ||
|         {
 | ||
|             case JToken jt:
 | ||
|                 return jt;
 | ||
| #if NET6_0_OR_GREATER
 | ||
|             case System.Text.Json.JsonElement elem:
 | ||
|                 return elem.ToJToken();
 | ||
| #endif
 | ||
|             case string s:
 | ||
|                 return new JValue(s);
 | ||
| 
 | ||
|             case bool b:
 | ||
|                 return new JValue(b);
 | ||
| 
 | ||
|             case int i:
 | ||
|                 return new JValue(i);
 | ||
| 
 | ||
|             case long l:
 | ||
|                 return new JValue(l);
 | ||
| 
 | ||
|             case double d:
 | ||
|                 return new JValue(d);
 | ||
| 
 | ||
|             case float f:
 | ||
|                 return new JValue(f);
 | ||
| 
 | ||
|             case decimal m:
 | ||
|                 return new JValue(m);
 | ||
| 
 | ||
|             case DateTime dt:
 | ||
|                 return new JValue(dt);
 | ||
| 
 | ||
|             case DateTimeOffset dto:
 | ||
|                 return new JValue(dto);
 | ||
| 
 | ||
|             case Guid g:
 | ||
|                 return new JValue(g);
 | ||
| 
 | ||
|             default:
 | ||
|                 // 兜底:用 Newtonsoft 来包装成 JToken
 | ||
|                 return JToken.FromObject(value);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     #region json
 | ||
| 
 | ||
|     /// <summary>
 | ||
|     /// 维度
 | ||
|     /// </summary>
 | ||
|     /// <param name="jToken"></param>
 | ||
|     /// <returns></returns>
 | ||
|     public static int CalculateActualValueRank(this JToken jToken)
 | ||
|     {
 | ||
|         if (jToken.Type != JTokenType.Array)
 | ||
|             return -1;
 | ||
| 
 | ||
|         var jArray = jToken.ToArray();
 | ||
|         int numDimensions = 1;
 | ||
| 
 | ||
|         while (jArray.GetElementsType() == JTokenType.Array)
 | ||
|         {
 | ||
|             jArray = jArray.Children().ToArray();
 | ||
|             numDimensions++;
 | ||
|         }
 | ||
|         return numDimensions;
 | ||
|     }
 | ||
| 
 | ||
|     private static JTokenType GetElementsType(this JToken[] jTokens)
 | ||
|     {
 | ||
|         return jTokens[0].Type;
 | ||
|     }
 | ||
| 
 | ||
|     #endregion json
 | ||
| }
 | 
