Files
serein-flow/Library/Api/IJsonProvider.cs
fengjiayi 1bccccc835 1. 重新设计了 JSON门户类的实现
2. Script脚本添加了原始字符串的实现
3. 修复了Script中无法对  \" 双引号转义的问题
4. 新增了对于集合嵌套取值的支持(目前仅是集合取值)
5. 重新设计了FlowWorkManagement任务启动的逻辑,修复了触发器无法正常运行的问题
6. 在ScriptBaseFunc中新增了 json() 本地函数,支持将字符串转为IJsonToken进行取值。
7. EmitHelper对于集合取值时,反射获取“get_item”委托时存在看你多个MethodInfo,现在可以传入子项类型,帮助匹配目标重载方法
2025-07-31 23:59:31 +08:00

301 lines
8.8 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Serein.Library.Api
{
/// <summary>
/// JSON数据交互的Token接口允许使用不同的JSON库进行数据处理。
/// </summary>
public interface IJsonToken
{
/// <summary>
/// 获取 Token
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
IJsonToken this[object name] { get; }
/* /// <summary>
/// 获取 Token 数组的元素,允许通过索引访问数组中的元素。
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
IJsonToken this[int index] { get; }*/
/// <summary>
/// 获取指定名称的属性如果存在则返回true并通过out参数返回对应的IJsonToken对象。
/// </summary>
/// <param name="name"></param>
/// <param name="token"></param>
/// <returns></returns>
bool TryGetValue(string name, out IJsonToken token);
/// <summary>
/// 获取指定名称的属性值如果不存在则返回null。
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
#nullable enable
IJsonToken? GetValue(string name);
/// <summary>
/// 获取当前Token的字符串值如果是null则返回null。
/// </summary>
/// <returns></returns>
string GetString();
/// <summary>
/// 获取当前Token的整数值如果是null则抛出异常。
/// </summary>
/// <returns></returns>
int GetInt32();
/// <summary>
/// 获取当前Token的布尔值如果是null则抛出异常。
/// </summary>
/// <returns></returns>
bool GetBoolean();
/// <summary>
/// 判断当前Token是否为null。
/// </summary>
bool IsNull { get; }
/// <summary>
/// 枚举当前Token作为数组时的所有元素返回一个IEnumerable&lt;IJsonTokens&gt;。
/// </summary>
/// <returns></returns>
IEnumerable<IJsonToken> EnumerateArray();
/// <summary>
/// 将当前Token转换为指定类型的对象。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T ToObject<T>();
/// <summary>
/// 将当前Token转换为指定类型的对象。
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
object ToObject(Type type);
/// <summary>
/// 将当前Token转换为字符串表示形式。
/// </summary>
/// <returns></returns>
string ToString();
}
/// <summary>
/// 使用Json进行数据交互的门户,允许外部使用第三方JSON库进行数据处理。
/// </summary>
public interface IJsonProvider
{
/// <summary>
/// JSON文本转为指定类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonText"></param>
/// <returns></returns>
T Deserialize<T>(string jsonText);
/// <summary>
/// JSON文本转为指定类型
/// </summary>
/// <param name="jsonText"></param>
/// <param name="type"></param>
/// <returns></returns>
object Deserialize(string jsonText, Type type);
/// <summary>
/// 从对象转换为JSON文本
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
string Serialize(object obj);
/// <summary>
/// 解析为Token
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
IJsonToken Parse(string json);
/// <summary>
/// 创建对象
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
IJsonToken CreateObject(IDictionary<string, object>? values = null);
/// <summary>
/// 创建数组
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
IJsonToken CreateArray(IEnumerable<object>? values = null);
/// <summary>
/// 将对象转换为JSON Token自动转换为 JObject/JArray。
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
IJsonToken FromObject(object obj);
}
}
/*
using System.Text.Json;
public class SystemTextJsonToken : IJsonToken
{
private readonly JsonElement _element;
public SystemTextJsonToken(JsonElement element) => _element = element;
public bool TryGetProperty(string name, out IJsonToken token)
{
if (_element.TryGetProperty(name, out var property))
{
token = new SystemTextJsonToken(property);
return true;
}
token = null;
return false;
}
public string GetString() => _element.ValueKind == JsonValueKind.Null ? null : _element.GetString();
public int GetInt32() => _element.GetInt32();
public bool GetBoolean() => _element.GetBoolean();
public bool IsNull => _element.ValueKind == JsonValueKind.Null;
public IEnumerable<IJsonToken> EnumerateArray()
{
if (_element.ValueKind == JsonValueKind.Array)
return _element.EnumerateArray().Select(e => new SystemTextJsonToken(e));
return Enumerable.Empty<IJsonToken>();
}
}
public class SystemTextJsonProvider : IJsonProvider
{
public string Serialize(object obj) => JsonSerializer.Serialize(obj);
public T Deserialize<T>(string json) => JsonSerializer.Deserialize<T>(json);
public IJsonToken Parse(string json) => new SystemTextJsonToken(JsonDocument.Parse(json).RootElement);
}
public T ToObject<T>()
{
// JsonElement -> string -> T
return JsonSerializer.Deserialize<T>(_element.GetRawText());
}
public IJsonToken CreateObject(IDictionary<string, object> values = null)
{
string json = values == null
? "{}"
: JsonSerializer.Serialize(values);
return Parse(json);
}
public IJsonToken CreateArray(IEnumerable<object> values = null)
{
string json = values == null
? "[]"
: JsonSerializer.Serialize(values);
return Parse(json);
}
public IJsonToken FromObject(object obj)
{
string json = JsonSerializer.Serialize(obj);
return Parse(json);
}
*/
/*
using Newtonsoft.Json.Linq;
public class NewtonsoftJsonToken : IJsonToken
{
private readonly JToken _token;
public NewtonsoftJsonToken(JToken token) => _token = token;
public bool TryGetProperty(string name, out IJsonToken token)
{
if (_token is JObject obj && obj.TryGetValue(name, out var value))
{
token = new NewtonsoftJsonToken(value);
return true;
}
token = null;
return false;
}
public string GetString() => _token.Type == JTokenType.Null ? null : _token.ToString();
public int GetInt32() => _token.Value<int>();
public bool GetBoolean() => _token.Value<bool>();
public bool IsNull => _token.Type == JTokenType.Null;
public IEnumerable<IJsonToken> EnumerateArray()
{
if (_token is JArray array)
return array.Select(x => new NewtonsoftJsonToken(x));
return Enumerable.Empty<IJsonToken>();
}
}
public class NewtonsoftJsonProvider : IJsonProvider
{
public string Serialize(object obj) => JsonConvert.SerializeObject(obj);
public T Deserialize<T>(string json) => JsonConvert.DeserializeObject<T>(json);
public IJsonToken Parse(string json) => new NewtonsoftJsonToken(JToken.Parse(json));
}
public T ToObject<T>()
{
return _token.ToObject<T>();
}
public IJsonToken CreateObject(IDictionary<string, object> values = null)
{
var obj = new JObject();
if (values != null)
{
foreach (var kvp in values)
{
obj[kvp.Key] = kvp.Value == null ? JValue.CreateNull() : JToken.FromObject(kvp.Value);
}
}
return new NewtonsoftJsonToken(obj);
}
public IJsonToken CreateArray(IEnumerable<object> values = null)
{
var array = values != null ? new JArray(values.Select(JToken.FromObject)) : new JArray();
return new NewtonsoftJsonToken(array);
}
public IJsonToken FromObject(object obj)
{
if (obj == null) return new NewtonsoftJsonToken(JValue.CreateNull());
if (obj is System.Collections.IEnumerable && !(obj is string))
return new NewtonsoftJsonToken(JArray.FromObject(obj));
return new NewtonsoftJsonToken(JObject.FromObject(obj));
}
*/