fix: fix hashSet deserialize error (#4545)
* update hangfire version to 1.8.5 * fix: fix hashSet deserialize error * fix: replace HashSet to ISet<T> * Update polymorphic converter and tests --------- Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
This commit is contained in:
parent
170a14c914
commit
4056434e45
|
|
@ -33,7 +33,6 @@ public class Fork : Activity
|
|||
/// <summary>
|
||||
/// The branches to schedule.
|
||||
/// </summary>
|
||||
[Port]
|
||||
public ICollection<IActivity> Branches { get; set; } = new List<IActivity>();
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
|||
|
|
@ -117,12 +117,15 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
|
||||
var values = model.TryGetProperty(ItemsPropertyName, out var itemsProp) ? itemsProp.EnumerateArray().ToList() : model.GetProperty(ValuesPropertyName).EnumerateArray().ToList();
|
||||
var id = model.TryGetProperty(IdPropertyName, out var idProp) ? idProp.GetString() : default;
|
||||
var collection = targetType.IsArray ? Array.CreateInstance(elementType, values.Count) : (IList)Activator.CreateInstance(targetType)!;
|
||||
var collection = targetType.IsArray ? Array.CreateInstance(elementType, values.Count) : Activator.CreateInstance(targetType)!;
|
||||
var index = 0;
|
||||
|
||||
if (id != null)
|
||||
referenceResolver?.AddReference(id, collection);
|
||||
|
||||
var isHashSet = targetType.GenericTypeArguments.Length == 1 && typeof(ISet<>).MakeGenericType(targetType.GenericTypeArguments[0]).IsAssignableFrom(targetType);
|
||||
var addSetMethod = targetType.GetMethod("Add", new[] { elementType })!;
|
||||
|
||||
foreach (var element in values)
|
||||
{
|
||||
var deserializedElement = JsonSerializer.Deserialize(JsonSerializer.Serialize(element), elementType, newOptions)!;
|
||||
|
|
@ -130,9 +133,13 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
{
|
||||
array.SetValue(deserializedElement, index++);
|
||||
}
|
||||
else
|
||||
else if (isHashSet)
|
||||
{
|
||||
collection.Add(deserializedElement);
|
||||
addSetMethod.Invoke(collection, new[] { deserializedElement });
|
||||
}
|
||||
else if (collection is IList list)
|
||||
{
|
||||
list.Add(deserializedElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +170,7 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
|
||||
// Special case for Newtonsoft.Json and System.Text.Json types.
|
||||
// Newtonsoft.Json types are not supported by the System.Text.Json serializer and should be written as a string instead.
|
||||
// We include metadata about the type so that we can deserialize it later.
|
||||
// We include metadata about the type so that we can deserialize it later.
|
||||
if (type == typeof(JObject) || type == typeof(JArray) || type == typeof(JsonObject) || type == typeof(JsonArray))
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
|
|
@ -200,7 +207,7 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
|
||||
value = sanitized;
|
||||
}
|
||||
|
||||
|
||||
var jsonElement = JsonDocument.Parse(JsonSerializer.Serialize(value, type, newOptions)).RootElement;
|
||||
|
||||
// If the value is a string, serialize it directly.
|
||||
|
|
@ -265,6 +272,7 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
case JsonTokenType.StartArray:
|
||||
depth++;
|
||||
break;
|
||||
|
||||
case JsonTokenType.EndObject:
|
||||
case JsonTokenType.EndArray:
|
||||
depth--;
|
||||
|
|
@ -309,6 +317,7 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
default:
|
||||
list.Add(Read(ref reader, typeof(object), options));
|
||||
break;
|
||||
|
||||
case JsonTokenType.EndArray:
|
||||
return list;
|
||||
}
|
||||
|
|
@ -328,6 +337,7 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
if (dict.Count == 1 && dict.TryGetValue(RefPropertyName, out var referencedObject))
|
||||
return referencedObject;
|
||||
return dict;
|
||||
|
||||
case JsonTokenType.PropertyName:
|
||||
var key = reader.GetString()!;
|
||||
reader.Read();
|
||||
|
|
@ -350,6 +360,7 @@ public class PolymorphicObjectConverter : JsonConverter<object>
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new JsonException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ public record Model(
|
|||
ICollection<Model>? Items = default,
|
||||
object? Metadata = default,
|
||||
object? Payload = default,
|
||||
IDictionary<string, Model>? Properties = default
|
||||
)
|
||||
object? HashSet = default,
|
||||
IDictionary<string, Model>? Properties = default)
|
||||
{
|
||||
public Model() : this(null, default, default, null, default, default, default)
|
||||
public Model() : this(null, default, default, null, default, default, default, default)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,33 +58,20 @@ public class Tests
|
|||
},
|
||||
metadata,
|
||||
new Model("Payload"),
|
||||
new HashSet<Model>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Text = "I'm a model in a set!"
|
||||
}
|
||||
},
|
||||
new Dictionary<string, Model>
|
||||
{
|
||||
["Hello"] = new("Hello", 1, true),
|
||||
["World"] = new("World", 2)
|
||||
["World"] = new("World", 2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private Model CreateModel2()
|
||||
{
|
||||
// Create a model with various nested properties
|
||||
var metadata = new ExpandoObject() as IDictionary<string, object>;
|
||||
|
||||
// Initialize metadata with test data.
|
||||
metadata["Models"] = new List<Model>
|
||||
{
|
||||
new(Text: "Hello World")
|
||||
};
|
||||
|
||||
return new Model(
|
||||
Metadata: metadata
|
||||
// Items : new List<Model>
|
||||
// {
|
||||
// new(Items: new List<Model> { new(Metadata: metadata) }),
|
||||
// }
|
||||
);
|
||||
}
|
||||
|
||||
private JsonSerializerOptions GetSerializerOptions()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"$id":"1","text":"Hello World","number":123,"flag":true,"items":{"$id":"2","$values":[{"$id":"3","text":"Hello","number":1,"flag":true,"items":{"$id":"4","$values":[{"$id":"5","number":0,"flag":false,"metadata":{"Foo":"Bar","Number":123,"Flag":true,"Models":{"$id":"6","$values":[{"$id":"7","text":"Hello","number":1,"flag":true,"metadata":{"Foo":"Bar","Number":123,"Flag":true,"Models":{"$ref":"6"},"CustomDictionary":{"$id":"8","content-type":["application/json"],"_type":"Elsa.IntegrationTests.Serialization.Polymorphism.CustomDictionary, Elsa.IntegrationTests"}}},{"$id":"9","text":"World","number":2,"flag":false}],"_type":"System.Collections.Generic.List\u00601[[Elsa.IntegrationTests.Serialization.Polymorphism.Model, Elsa.IntegrationTests]], System.Private.CoreLib"},"CustomDictionary":{"$ref":"8"}}}]}},{"$id":"10","text":"World","number":2,"flag":false}]},"metadata":{"Foo":"Bar","Number":123,"Flag":true,"Models":{"$ref":"6"},"CustomDictionary":{"$ref":"8"}},"payload":{"$id":"11","text":"Payload","number":0,"flag":false,"_type":"Elsa.IntegrationTests.Serialization.Polymorphism.Model, Elsa.IntegrationTests"},"properties":{"$id":"12","Hello":{"$id":"13","text":"Hello","number":1,"flag":true},"World":{"$id":"14","text":"World","number":2,"flag":false}}}
|
||||
{"$id":"1","text":"Hello World","number":123,"flag":true,"items":{"$id":"2","$values":[{"$id":"3","text":"Hello","number":1,"flag":true,"items":{"$id":"4","$values":[{"$id":"5","number":0,"flag":false,"metadata":{"Foo":"Bar","Number":123,"Flag":true,"Models":{"$id":"6","$values":[{"$id":"7","text":"Hello","number":1,"flag":true,"metadata":{"Foo":"Bar","Number":123,"Flag":true,"Models":{"$ref":"6"},"CustomDictionary":{"$id":"8","content-type":["application/json"],"_type":"Elsa.IntegrationTests.Serialization.Polymorphism.CustomDictionary, Elsa.IntegrationTests"}}},{"$id":"9","text":"World","number":2,"flag":false}],"_type":"System.Collections.Generic.List\u00601[[Elsa.IntegrationTests.Serialization.Polymorphism.Model, Elsa.IntegrationTests]], System.Private.CoreLib"},"CustomDictionary":{"$ref":"8"}}}]}},{"$id":"10","text":"World","number":2,"flag":false}]},"metadata":{"Foo":"Bar","Number":123,"Flag":true,"Models":{"$ref":"6"},"CustomDictionary":{"$ref":"8"}},"payload":{"$id":"11","text":"Payload","number":0,"flag":false,"_type":"Elsa.IntegrationTests.Serialization.Polymorphism.Model, Elsa.IntegrationTests"},"hashSet":{"$id":"12","$values":[{"$id":"13","text":"I\u0027m a model in a set!","number":0,"flag":false}],"_type":"System.Collections.Generic.HashSet\u00601[[Elsa.IntegrationTests.Serialization.Polymorphism.Model, Elsa.IntegrationTests]], System.Private.CoreLib"},"properties":{"$id":"14","Hello":{"$id":"15","text":"Hello","number":1,"flag":true},"World":{"$id":"16","text":"World","number":2,"flag":false}}}
|
||||
Loading…
Reference in a new issue