using System.Collections; using System.Text.Json; using System.Text.Json.Nodes; using Newtonsoft.Json.Linq; namespace Caspian.WorkflowFramework.Utility; public static class WorkflowVariableExtensions { private const string SessionIdKey = "SessionId"; /// /// sessionId را از دیکشنری اصلی و تمام مقادیر تو در تو حذف می‌کند. /// public static Dictionary RemoveSessionId( this Dictionary variables) { if (variables == null || variables.Count == 0) return variables; RemoveSessionIdKeys(variables); foreach (var key in variables.Keys.ToList()) variables[key] = RemoveSessionIdRecursive(variables[key]); return variables; } private static object? RemoveSessionIdRecursive(object? value) { if (value == null) return null; switch (value) { // Dictionary و ExpandoObject case IDictionary dictionary: { RemoveSessionIdKeys(dictionary); foreach (var key in dictionary.Keys.ToList()) dictionary[key] = RemoveSessionIdRecursive(dictionary[key]); return value; } // System.Text.Json.Nodes case JsonObject jsonObject: { RemoveSessionIdKeys(jsonObject); foreach (var property in jsonObject.ToList()) jsonObject[property.Key] = RemoveSessionIdFromJsonNode(property.Value); return jsonObject; } case JsonArray jsonArray: { for (var i = 0; i < jsonArray.Count; i++) { jsonArray[i] = RemoveSessionIdFromJsonNode(jsonArray[i]); } return jsonArray; } // JsonElement تغییرپذیر نیست؛ پس نسخه پاک‌سازی‌شده می‌سازیم. case JsonElement jsonElement: { var node = JsonNode.Parse(jsonElement.GetRawText()); if (node == null) return jsonElement; var cleanedNode = RemoveSessionIdFromJsonNode(node); return cleanedNode == null ? jsonElement : JsonSerializer.SerializeToElement(cleanedNode); } // Newtonsoft.Json case JObject jObject: { RemoveSessionIdKeys(jObject); foreach (var property in jObject.Properties().ToList()) property.Value = RemoveSessionIdFromJToken(property.Value); return jObject; } case JArray jArray: { for (var i = 0; i < jArray.Count; i++) jArray[i] = RemoveSessionIdFromJToken(jArray[i]); return jArray; } // سایر لیست‌ها و آرایه‌ها case IList list: { for (var i = 0; i < list.Count; i++) list[i] = RemoveSessionIdRecursive(list[i]); return list; } case IEnumerable enumerable when value is not string: { foreach (var child in enumerable) RemoveSessionIdRecursive(child); return value; } default: return value; } } private static JsonNode? RemoveSessionIdFromJsonNode(JsonNode? node) { if (node == null) return null; switch (node) { case JsonObject jsonObject: { RemoveSessionIdKeys(jsonObject); foreach (var property in jsonObject.ToList()) { jsonObject[property.Key] = RemoveSessionIdFromJsonNode(property.Value); } break; } case JsonArray jsonArray: { for (var i = 0; i < jsonArray.Count; i++) { jsonArray[i] = RemoveSessionIdFromJsonNode(jsonArray[i]); } break; } } return node; } private static JToken RemoveSessionIdFromJToken(JToken token) { switch (token) { case JObject jObject: { RemoveSessionIdKeys(jObject); foreach (var property in jObject.Properties().ToList()) property.Value = RemoveSessionIdFromJToken(property.Value); break; } case JArray jArray: { for (var i = 0; i < jArray.Count; i++) jArray[i] = RemoveSessionIdFromJToken(jArray[i]); break; } } return token; } private static void RemoveSessionIdKeys( IDictionary dictionary) { var keys = dictionary.Keys .Where(IsSessionId) .ToList(); foreach (var key in keys) dictionary.Remove(key); } private static void RemoveSessionIdKeys(JsonObject jsonObject) { var keys = jsonObject .Select(x => x.Key) .Where(IsSessionId) .ToList(); foreach (var key in keys) jsonObject.Remove(key); } private static void RemoveSessionIdKeys(JObject jObject) { var properties = jObject.Properties() .Where(x => IsSessionId(x.Name)) .ToList(); foreach (var property in properties) property.Remove(); } private static bool IsSessionId(string key) { return string.Equals( key, SessionIdKey, StringComparison.OrdinalIgnoreCase); } }