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.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Newtonsoft.Json.Linq;
using NJsonSchema.Converters;
using Squidex.Infrastructure;
#pragma warning disable RECS0108 // Warns about static fields in generic types
namespace Squidex.Areas.Api.Controllers
{
public class MyJsonInheritanceConverter : JsonInheritanceConverter
public class MyJsonInheritanceConverter<T> : JsonInheritanceConverter
{
private readonly IDictionary<string, Type> mapping;
private readonly Type baseType;
private static readonly Dictionary<string, Type> DefaultMapping = new Dictionary<string, Type>();
private readonly IReadOnlyDictionary<string, Type> maping;
public MyJsonInheritanceConverter(string discriminator, Type baseType)
: base(baseType, discriminator)
static MyJsonInheritanceConverter()
{
this.baseType = baseType;
}
var baseName = typeof(T).Name;
public MyJsonInheritanceConverter(string discriminator, Type baseType, IDictionary<string, Type> mapping)
: this(discriminator, baseType)
{
this.mapping = mapping;
}
void AddType(Type type)
{
var discriminator = type.Name;
public override string GetDiscriminatorValue(Type type)
{
var result = type.Name;
if (discriminator.EndsWith(baseName, StringComparison.CurrentCulture))
{
discriminator = discriminator.Substring(0, discriminator.Length - baseName.Length);
}
if (baseType != null)
{
var baseName = baseType.Name;
DefaultMapping[discriminator] = type;
}
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.
/// </summary>
[Required]
[JsonConverter(typeof(RuleActionSerializer))]
[JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; }
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.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Extensions.Actions;
namespace Squidex.Areas.Api.Controllers.Rules.Models
{
public sealed class RuleActionSerializer : MyJsonInheritanceConverter
public sealed class RuleActionConverter : MyJsonInheritanceConverter<RuleAction>
{
public RuleActionSerializer()
: base("actionType", typeof(RuleAction), RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => x.Value.Type))
private static readonly Dictionary<string, Type> Mapping = 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)
{
var discriminator = new OpenApiDiscriminator
schema.DiscriminatorObject = new OpenApiDiscriminator
{
JsonInheritanceConverter = new MyJsonInheritanceConverter("actionType", typeof(RuleAction)),
PropertyName = "actionType"
JsonInheritanceConverter = new RuleActionConverter(), PropertyName = "actionType"
};
schema.DiscriminatorObject = discriminator;
schema.Properties["actionType"] = new JsonProperty
{
Type = JsonObjectType.String,
IsRequired = true
Type = JsonObjectType.String, IsRequired = true
};
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.
/// </summary>
[Required]
[JsonConverter(typeof(RuleActionSerializer))]
[JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; }
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
{
[JsonConverter(typeof(MyJsonInheritanceConverter), "triggerType", typeof(RuleTriggerDto))]
[JsonConverter(typeof(MyJsonInheritanceConverter<RuleTriggerDto>), "triggerType")]
[KnownType(nameof(Subtypes))]
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>
/// The action properties.
/// </summary>
[JsonConverter(typeof(RuleActionSerializer))]
[JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; }
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
{
[JsonConverter(typeof(MyJsonInheritanceConverter), "fieldType", typeof(FieldPropertiesDto))]
[JsonConverter(typeof(MyJsonInheritanceConverter<FieldPropertiesDto>), "fieldType")]
[KnownType(nameof(Subtypes))]
public abstract class FieldPropertiesDto
{

Loading…
Cancel
Save