Files
ThingsGateway/src/Admin/ThingsGateway.NewLife.X/Extension/JTokenUtil.cs
2025-09-18 17:15:57 +08:00

221 lines
6.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人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
}