Consider sessionId in publish event +

Upgrade package to 1.1.0-preview.21
This commit is contained in:
Behzad Alizadeh
2026-07-22 10:52:25 +03:30
parent 2b15c8a1af
commit 83738f809b
7 changed files with 310 additions and 63 deletions
@@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<PackageId>Caspian.WorkflowFramework</PackageId> <PackageId>Caspian.WorkflowFramework</PackageId>
<Version>1.1.0-preview.20</Version> <Version>1.1.0-preview.21</Version>
<Authors>Behzad Alizadeh</Authors> <Authors>Behzad Alizadeh</Authors>
<Company>Caspian</Company> <Company>Caspian</Company>
<Product>Caspian.WorkflowFramework</Product> <Product>Caspian.WorkflowFramework</Product>
@@ -17,58 +17,61 @@
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile> <PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>caspian-pkg-key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>caspian-pkg-key.snk</AssemblyOriginatorKeyFile>
<PackageOutputPath>
$(MSBuildThisFileDirectory)packages
</PackageOutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Caspian.Elsa.WorkflowContexts" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.WorkflowContexts" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Workflows.Runtime.Distributed" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Workflows.Runtime.Distributed" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Alterations" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Alterations" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Alterations.MassTransit" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Alterations.MassTransit" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Caching.Distributed.MassTransit" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Caching.Distributed.MassTransit" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Caching.Distributed.ProtoActor" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Caching.Distributed.ProtoActor" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.CSharp" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.CSharp" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Dapper" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Dapper" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Dapper.Migrations" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Dapper.Migrations" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.DropIns" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.DropIns" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Email" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Email" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Elasticsearch" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Elasticsearch" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Environments" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Environments" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.EntityFrameworkCore" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.MySql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.EntityFrameworkCore.MySql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Oracle" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Oracle" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.PostgreSql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.EntityFrameworkCore.PostgreSql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Sqlite" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Sqlite" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.SqlServer" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.EntityFrameworkCore.SqlServer" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.FileStorage" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.FileStorage" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Hangfire" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Hangfire" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Http" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Http" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Identity" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Identity" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Kafka" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Kafka" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Labels" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Labels" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Liquid" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Liquid" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.MassTransit" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.MassTransit" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.MassTransit.AzureServiceBus" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.MassTransit.AzureServiceBus" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.MassTransit.RabbitMq" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.MassTransit.RabbitMq" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.MongoDb" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.MongoDb" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.OpenTelemetry" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.OpenTelemetry" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Quartz" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Quartz" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.MySql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.MySql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.PostgreSql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.PostgreSql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.Sqlite" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.Sqlite" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Retention" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Retention" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Secrets.Api" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Secrets.Api" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Secrets.Persistence.EntityFrameworkCore.PostgreSql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Secrets.Persistence.EntityFrameworkCore.PostgreSql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Secrets.Persistence.EntityFrameworkCore.SqlServer" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Secrets.Persistence.EntityFrameworkCore.SqlServer" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Secrets.Scripting" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Secrets.Scripting" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Sql.MySql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Sql.MySql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Sql.PostgreSql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Sql.PostgreSql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Sql.Sqlite" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Sql.Sqlite" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Sql.SqlServer" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Sql.SqlServer" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Sql" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Sql" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Tenants.AspNetCore" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Tenants.AspNetCore" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa.Webhooks" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa.Webhooks" Version="1.1.0-preview.8" />
<PackageReference Include="Caspian.Elsa" Version="1.1.0-preview.7" /> <PackageReference Include="Caspian.Elsa" Version="1.1.0-preview.8" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" /> <PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" />
@@ -14,4 +14,6 @@ public class PublishEventModel
[Required] [Required]
public JsonElement EventData { get; set; } public JsonElement EventData { get; set; }
public string? SessionId { get; set; }
} }
@@ -14,6 +14,7 @@ using Elsa.Workflows.Runtime.Messages;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using San.MongoLogger; using San.MongoLogger;
using System.Diagnostics; using System.Diagnostics;
using System.Dynamic; using System.Dynamic;
@@ -292,22 +293,34 @@ public class WorkflowService : IWorkflowService, ILoggable
return response; return response;
} }
dynamic payload = null; ExpandoObject payload;
if (input.EventData.ValueKind != JsonValueKind.Undefined && var payloadObject = new JObject();
input.EventData.ValueKind != JsonValueKind.Null)
if (input.EventData.ValueKind is not JsonValueKind.Undefined
and not JsonValueKind.Null)
{ {
var json = input.EventData.GetRawText(); if (input.EventData.ValueKind != JsonValueKind.Object)
throw new InvalidOperationException("EventData must be a JSON object.");
var settings = new JsonSerializerSettings payloadObject = JObject.Parse(input.EventData.GetRawText());
{
Converters = { new ExpandoObjectConverter() }
};
// تبدیل JSON به object داینامیک
payload = JsonConvert.DeserializeObject<ExpandoObject>(json, settings);
} }
if (!string.IsNullOrWhiteSpace(input.SessionId))
{
payloadObject["SessionId"] = input.SessionId;
}
var settings = new JsonSerializerSettings
{
Converters = { new ExpandoObjectConverter() }
};
payload = JsonConvert.DeserializeObject<ExpandoObject>(
payloadObject.ToString(Formatting.None),
settings
) ?? new ExpandoObject();
//await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, input.EventData, asynchronous: true); //await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, input.EventData, asynchronous: true);
await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, payload); await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, payload);
@@ -18,6 +18,9 @@ namespace Caspian.WorkflowFramework.Utility
if (dictionary == null || dictionary.Count == 0) if (dictionary == null || dictionary.Count == 0)
return workflowModel; return workflowModel;
// قبل از تبدیل به مدل خروجی، sessionId حذف می‌شود.
dictionary.RemoveSessionId();
//Map dictionary values to WorkflowModel properties //Map dictionary values to WorkflowModel properties
workflowModel.InstanceId = dictionary.ContainsKey(nameof(workflowModel.InstanceId)) workflowModel.InstanceId = dictionary.ContainsKey(nameof(workflowModel.InstanceId))
? dictionary[nameof(workflowModel.InstanceId)]?.ToString() ? dictionary[nameof(workflowModel.InstanceId)]?.ToString()
@@ -0,0 +1,226 @@
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";
/// <summary>
/// sessionId را از دیکشنری اصلی و تمام مقادیر تو در تو حذف می‌کند.
/// </summary>
public static Dictionary<string, object?> RemoveSessionId(
this Dictionary<string, object?> 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<string, object?> 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<string, object?> 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);
}
}
+1 -1
View File
@@ -9,6 +9,6 @@
<add key="Local Package source" value="D:\MyNugetPackages" /> <add key="Local Package source" value="D:\MyNugetPackages" />
<add key="Workflow Package source" value="D:\NugetPackageRepository\WorkflowPackages" /> <add key="Workflow Package source" value="D:\NugetPackageRepository\WorkflowPackages" />
<add key="Caspian package source" value="https://nuget.caspian.com/v3/index.json" /> <add key="Caspian package source" value="https://nuget.caspian.com/v3/index.json" />
<add key="Liara Package source" value="D:\CaspianProjects\NugetPackageRepositoryLiara\AllPackages" /> <add key="Gitea Package source" value="D:\CaspianProjects\NugetPackageRepository\AllPackages" />
</packageSources> </packageSources>
</configuration> </configuration>
+1 -1
View File
@@ -7,7 +7,7 @@
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Data Source=.;Initial Catalog=WfDb;User ID=sa;Password=123456;Integrated Security=false;TrustServerCertificate=True;" "DefaultConnection": "Data Source=.;Initial Catalog=WfLive;User ID=sa;Password=123456;Integrated Security=false;TrustServerCertificate=True;"
}, },
"LogDatabaseSettings": { "LogDatabaseSettings": {
"LogsCollectionName": "TestWorkflowCollection", "LogsCollectionName": "TestWorkflowCollection",