Merge branch 'main' into feature/4835

This commit is contained in:
Sipke Schoorstra 2025-01-29 13:39:31 +01:00
commit 7f86799393
No known key found for this signature in database
GPG key ID: 5C10502B28A4268F
5 changed files with 65 additions and 7 deletions

View file

@ -1,4 +1,5 @@
using System.Collections;
using System.Dynamic;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
@ -183,6 +184,22 @@ public class SendEmail : Activity
else if (emailAttachment.Content is Stream stream)
await bodyBuilder.Attachments.AddAsync(fileName, stream, parsedContentType, cancellationToken);
break;
}
case ExpandoObject expandoObject:
{
var dictionary = new Dictionary<string, object>(expandoObject, StringComparer.OrdinalIgnoreCase);
var fileName = dictionary.GetValue<string>("FileName") ?? $"Attachment-{++index}";
var contentType = dictionary.GetValue<string>("ContentType") ?? "application/binary";
var parsedContentType = ContentType.Parse(contentType);
var content = dictionary.GetValue<object>("Content");
if (content is byte[] bytes)
bodyBuilder.Attachments.Add(fileName, bytes, parsedContentType);
else if (content is Stream stream)
await bodyBuilder.Attachments.AddAsync(fileName, stream, parsedContentType, cancellationToken);
break;
}
default:

View file

@ -15,6 +15,7 @@
<ItemGroup>
<ProjectReference Include="..\..\common\Elsa.Features\Elsa.Features.csproj" />
<ProjectReference Include="..\Elsa.Common\Elsa.Common.csproj" />
</ItemGroup>
</Project>

View file

@ -102,15 +102,29 @@ public static class ObjectConverter
return jsonElement.Deserialize(targetType, serializerOptions);
}
if (value is JsonNode jsonNode and not JsonArray) // If the value is a JsonNode, we can convert it to the target type. If it's a JsonArray, we let the enumerable conversion logic handle it.
if (value is JsonNode jsonNode)
{
return underlyingTargetType switch
if (jsonNode is not JsonArray jsonArray)
{
{ } t when t == typeof(string) => jsonNode.ToString(),
{ } t when t == typeof(ExpandoObject) && jsonNode.GetValueKind() == JsonValueKind.Object => JsonSerializer.Deserialize<ExpandoObject>(jsonNode.ToJsonString()),
{ } t when t != typeof(object) || converterOptions?.DeserializeJsonObjectToObject == true => jsonNode.Deserialize(targetType, serializerOptions),
_ => jsonNode
};
return underlyingTargetType switch
{
{ } t when t == typeof(string) => jsonNode.ToString(),
{ } t when t == typeof(ExpandoObject) && jsonNode.GetValueKind() == JsonValueKind.Object => JsonSerializer.Deserialize<ExpandoObject>(jsonNode.ToJsonString()),
{ } t when t != typeof(object) || converterOptions?.DeserializeJsonObjectToObject == true => jsonNode.Deserialize(targetType, serializerOptions),
_ => jsonNode
};
}
// Convert to target type if target type is an array or a generic collection.
if (targetType.IsArray || targetType.IsCollectionType())
{
// The element type of the source array is JsonObject. If the element type of the target array is Object then return the source array as an array of JsonObjects.
// Deserializing normally would return an array of JsonElement instead of JsonObject, but we want to keep JsonObject elements:
var targetElementType = targetType.IsArray ? targetType.GetElementType()! : targetType.GenericTypeArguments[0];
if (targetElementType != typeof(object))
return jsonArray.Deserialize(targetType, serializerOptions);
}
}
if (underlyingSourceType == typeof(string) && !underlyingTargetType.IsPrimitive && underlyingTargetType != typeof(object))

View file

@ -0,0 +1,9 @@
namespace Elsa.Workflows.Core.UnitTests.ObjectConversion
{
public class Person
{
public double? Age { get; set; }
public string? Name { get; set; }
}
}

View file

@ -283,4 +283,21 @@ public class Tests
Assert.Equal("Bob", secondElement["name"]?.ToString());
Assert.Equal("25", secondElement["age"]?.ToString());
}
[Fact]
public void ConvertFrom_JsonArrayToArrayOfComplextType_ReturnsArrayOfComplexType()
{
// Arrange
var jsonArrayString = "[{\"name\":\"Alice\",\"age\":30},{\"name\":\"Bob\",\"age\":25}]";
var options = new ObjectConverterOptions();
// Act
var result = jsonArrayString.ConvertTo<Person[]>(options);
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.Length);
Assert.Equal("Alice", result[0].Name);
Assert.Equal("Bob", result[1].Name);
}
}