Browse Source

Serialization fixes.

pull/337/head
Sebastian Stehle 8 years ago
parent
commit
f905855720
  1. 85
      src/Squidex/Areas/Api/Controllers/MyJsonInheritanceConverter.cs
  2. 2
      src/Squidex/Areas/Api/Controllers/Rules/Models/CreateRuleDto.cs
  3. 10
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionConverter.cs
  4. 9
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs
  5. 2
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs
  6. 2
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleTriggerDto.cs
  7. 2
      src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs
  8. 2
      src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldPropertiesDto.cs

85
src/Squidex/Areas/Api/Controllers/MyJsonInheritanceConverter.cs

@ -8,42 +8,85 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Newtonsoft.Json.Linq;
using NJsonSchema.Converters; using NJsonSchema.Converters;
using Squidex.Infrastructure;
#pragma warning disable RECS0108 // Warns about static fields in generic types
namespace Squidex.Areas.Api.Controllers namespace Squidex.Areas.Api.Controllers
{ {
public class MyJsonInheritanceConverter : JsonInheritanceConverter public class MyJsonInheritanceConverter<T> : JsonInheritanceConverter
{ {
private readonly IDictionary<string, Type> mapping; private static readonly Dictionary<string, Type> DefaultMapping = new Dictionary<string, Type>();
private readonly Type baseType; private readonly IReadOnlyDictionary<string, Type> maping;
public MyJsonInheritanceConverter(string discriminator, Type baseType) static MyJsonInheritanceConverter()
: base(baseType, discriminator)
{ {
this.baseType = baseType; var baseName = typeof(T).Name;
}
public MyJsonInheritanceConverter(string discriminator, Type baseType, IDictionary<string, Type> mapping) void AddType(Type type)
: this(discriminator, baseType) {
{ var discriminator = type.Name;
this.mapping = mapping;
}
public override string GetDiscriminatorValue(Type type) if (discriminator.EndsWith(baseName, StringComparison.CurrentCulture))
{ {
var result = type.Name; discriminator = discriminator.Substring(0, discriminator.Length - baseName.Length);
}
if (baseType != null) DefaultMapping[discriminator] = type;
{ }
var baseName = baseType.Name;
if (result.EndsWith(baseName, StringComparison.CurrentCulture)) foreach (var attribute in typeof(T).GetCustomAttributes<KnownTypeAttribute>())
{
if (attribute.Type != null)
{
if (!attribute.Type.IsAbstract)
{
AddType(attribute.Type);
}
}
else if (!string.IsNullOrWhiteSpace(attribute.MethodName))
{ {
return result.Substring(0, result.Length - baseName.Length); var method = typeof(T).GetMethod(attribute.MethodName);
if (method != null && method.IsStatic)
{
var types = (IEnumerable<Type>)method.Invoke(null, new object[0]);
foreach (var type in types)
{
if (!type.IsAbstract)
{
AddType(type);
}
}
}
} }
} }
}
public MyJsonInheritanceConverter(string discriminator)
: this(discriminator, DefaultMapping)
{
}
public MyJsonInheritanceConverter(string discriminator, IReadOnlyDictionary<string, Type> mapping)
: base(typeof(T), discriminator)
{
maping = mapping;
}
return mapping?.FirstOrDefault(x => x.Value == type).Key ?? result; protected override Type GetDiscriminatorType(JObject jObject, Type objectType, string discriminatorValue)
{
return maping.GetOrDefault(discriminatorValue) ?? throw new InvalidOperationException($"Could not find subtype of '{objectType.Name}' with discriminator '{discriminatorValue}'.");
}
public override string GetDiscriminatorValue(Type type)
{
return maping.FirstOrDefault(x => x.Value == type).Key ?? type.Name;
} }
} }
} }

2
src/Squidex/Areas/Api/Controllers/Rules/Models/CreateRuleDto.cs

@ -24,7 +24,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
/// The action properties. /// The action properties.
/// </summary> /// </summary>
[Required] [Required]
[JsonConverter(typeof(RuleActionSerializer))] [JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; } public RuleAction Action { get; set; }
public CreateRule ToCommand() public CreateRule ToCommand()

10
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionSerializer.cs → src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionConverter.cs

@ -5,16 +5,20 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Extensions.Actions; using Squidex.Extensions.Actions;
namespace Squidex.Areas.Api.Controllers.Rules.Models namespace Squidex.Areas.Api.Controllers.Rules.Models
{ {
public sealed class RuleActionSerializer : MyJsonInheritanceConverter public sealed class RuleActionConverter : MyJsonInheritanceConverter<RuleAction>
{ {
public RuleActionSerializer() private static readonly Dictionary<string, Type> Mapping = RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => x.Value.Type);
: base("actionType", typeof(RuleAction), RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => x.Value.Type))
public RuleActionConverter()
: base("actionType", Mapping)
{ {
} }
} }

9
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs

@ -26,17 +26,14 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
if (schema != null) if (schema != null)
{ {
var discriminator = new OpenApiDiscriminator schema.DiscriminatorObject = new OpenApiDiscriminator
{ {
JsonInheritanceConverter = new MyJsonInheritanceConverter("actionType", typeof(RuleAction)), JsonInheritanceConverter = new RuleActionConverter(), PropertyName = "actionType"
PropertyName = "actionType"
}; };
schema.DiscriminatorObject = discriminator;
schema.Properties["actionType"] = new JsonProperty schema.Properties["actionType"] = new JsonProperty
{ {
Type = JsonObjectType.String, Type = JsonObjectType.String, IsRequired = true
IsRequired = true
}; };
foreach (var derived in RuleElementRegistry.Actions) foreach (var derived in RuleElementRegistry.Actions)

2
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs

@ -67,7 +67,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
/// The action properties. /// The action properties.
/// </summary> /// </summary>
[Required] [Required]
[JsonConverter(typeof(RuleActionSerializer))] [JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; } public RuleAction Action { get; set; }
public static RuleDto FromRule(IRuleEntity rule) public static RuleDto FromRule(IRuleEntity rule)

2
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleTriggerDto.cs

@ -13,7 +13,7 @@ using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Areas.Api.Controllers.Rules.Models namespace Squidex.Areas.Api.Controllers.Rules.Models
{ {
[JsonConverter(typeof(MyJsonInheritanceConverter), "triggerType", typeof(RuleTriggerDto))] [JsonConverter(typeof(MyJsonInheritanceConverter<RuleTriggerDto>), "triggerType")]
[KnownType(nameof(Subtypes))] [KnownType(nameof(Subtypes))]
public abstract class RuleTriggerDto public abstract class RuleTriggerDto
{ {

2
src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs

@ -22,7 +22,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
/// <summary> /// <summary>
/// The action properties. /// The action properties.
/// </summary> /// </summary>
[JsonConverter(typeof(RuleActionSerializer))] [JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; } public RuleAction Action { get; set; }
public UpdateRule ToCommand(Guid id) public UpdateRule ToCommand(Guid id)

2
src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldPropertiesDto.cs

@ -14,7 +14,7 @@ using Squidex.Domain.Apps.Core.Schemas;
namespace Squidex.Areas.Api.Controllers.Schemas.Models namespace Squidex.Areas.Api.Controllers.Schemas.Models
{ {
[JsonConverter(typeof(MyJsonInheritanceConverter), "fieldType", typeof(FieldPropertiesDto))] [JsonConverter(typeof(MyJsonInheritanceConverter<FieldPropertiesDto>), "fieldType")]
[KnownType(nameof(Subtypes))] [KnownType(nameof(Subtypes))]
public abstract class FieldPropertiesDto public abstract class FieldPropertiesDto
{ {

Loading…
Cancel
Save