diff --git a/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs
index a42d030f5..fd7b6d533 100644
--- a/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs
+++ b/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs
@@ -36,6 +36,18 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
}
}
+ protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
+ {
+ if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>))
+ {
+ var implementationType = typeof(Dictionary<,>).MakeGenericType(objectType.GetGenericArguments());
+
+ return base.CreateDictionaryContract(implementationType);
+ }
+
+ return base.CreateDictionaryContract(objectType);
+ }
+
protected override JsonConverter ResolveContractConverter(Type objectType)
{
var result = base.ResolveContractConverter(objectType);
diff --git a/src/Squidex/app/features/settings/pages/workflows/workflow-step.component.html b/src/Squidex/app/features/settings/pages/workflows/workflow-step.component.html
index 158b89134..57c22536d 100644
--- a/src/Squidex/app/features/settings/pages/workflows/workflow-step.component.html
+++ b/src/Squidex/app/features/settings/pages/workflows/workflow-step.component.html
@@ -20,7 +20,7 @@
+ [disabled]="step.isLocked || disabled">
diff --git a/tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs b/tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs
index e6e9b36d5..9452cf681 100644
--- a/tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs
+++ b/tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs
@@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Core
var serializerSettings = new JsonSerializerSettings
{
- SerializationBinder = new TypeNameSerializationBinder(typeNameRegistry),
+ SerializationBinder = new ReadOnlyDictionaryBinder(new TypeNameSerializationBinder(typeNameRegistry)),
ContractResolver = new ConverterContractResolver(
new AppClientsConverter(),
diff --git a/tests/Squidex.Infrastructure.Tests/Json/Newtonsoft/ReadOnlyDictionaryTests.cs b/tests/Squidex.Infrastructure.Tests/Json/Newtonsoft/ReadOnlyDictionaryTests.cs
new file mode 100644
index 000000000..2d3ed2869
--- /dev/null
+++ b/tests/Squidex.Infrastructure.Tests/Json/Newtonsoft/ReadOnlyDictionaryTests.cs
@@ -0,0 +1,46 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Xunit;
+
+namespace Squidex.Infrastructure.Json.Newtonsoft
+{
+ public class ReadOnlyDictionaryTests
+ {
+ public sealed class MyClass
+ {
+ public IReadOnlyDictionary Values { get; set; }
+ }
+
+ [Fact]
+ public void Should_serialize_and_deserialize_without_type_name()
+ {
+ var source = new MyClass
+ {
+ Values = new Dictionary
+ {
+ [2] = 4,
+ [3] = 9
+ }
+ };
+
+ var serializerSettings = new JsonSerializerSettings
+ {
+ ContractResolver = new ConverterContractResolver()
+ };
+
+ var json = JsonConvert.SerializeObject(source, serializerSettings);
+
+ var serialized = JsonConvert.DeserializeObject(json);
+
+ Assert.DoesNotContain("$type", json);
+ Assert.Equal(2, serialized.Values.Count);
+ }
+ }
+}