mirror of https://github.com/abpframework/abp.git
57 changed files with 783 additions and 329 deletions
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Json.Microsoft; |
|||
using Volo.Abp.Json.Microsoft.JsonConverters; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public class AbpJsonOptionsSetup : IConfigureOptions<JsonOptions> |
|||
{ |
|||
protected IServiceProvider ServiceProvider { get; } |
|||
|
|||
public AbpJsonOptionsSetup(IServiceProvider serviceProvider) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
|
|||
public void Configure(JsonOptions options) |
|||
{ |
|||
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService<AbpDateTimeConverter>()); |
|||
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>()); |
|||
} |
|||
} |
|||
} |
|||
@ -1,46 +0,0 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Serialization; |
|||
using System; |
|||
using System.Reflection; |
|||
using Volo.Abp.Json.Newtonsoft; |
|||
using Volo.Abp.Reflection; |
|||
using Volo.Abp.Timing; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public class AbpMvcJsonContractResolver : DefaultContractResolver |
|||
{ |
|||
private readonly Lazy<AbpJsonIsoDateTimeConverter> _dateTimeConverter; |
|||
|
|||
public AbpMvcJsonContractResolver(IServiceCollection services) |
|||
{ |
|||
_dateTimeConverter = services.GetServiceLazy<AbpJsonIsoDateTimeConverter>(); |
|||
|
|||
NamingStrategy = new CamelCaseNamingStrategy(); |
|||
} |
|||
|
|||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) |
|||
{ |
|||
JsonProperty property = base.CreateProperty(member, memberSerialization); |
|||
|
|||
ModifyProperty(member, property); |
|||
|
|||
return property; |
|||
} |
|||
|
|||
protected virtual void ModifyProperty(MemberInfo member, JsonProperty property) |
|||
{ |
|||
if (property.PropertyType != typeof(DateTime) && property.PropertyType != typeof(DateTime?)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableDateTimeNormalizationAttribute>(member) == null) |
|||
{ |
|||
property.Converter = _dateTimeConverter.Value; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,39 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Serialization; |
|||
|
|||
namespace Volo.Abp.Auditing |
|||
{ |
|||
public class AuditingContractResolver : CamelCasePropertyNamesContractResolver |
|||
{ |
|||
private readonly List<Type> _ignoredTypes; |
|||
|
|||
public AuditingContractResolver(List<Type> ignoredTypes) |
|||
{ |
|||
_ignoredTypes = ignoredTypes; |
|||
} |
|||
|
|||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) |
|||
{ |
|||
var property = base.CreateProperty(member, memberSerialization); |
|||
|
|||
if (member.IsDefined(typeof(DisableAuditingAttribute)) || member.IsDefined(typeof(JsonIgnoreAttribute))) |
|||
{ |
|||
property.ShouldSerialize = instance => false; |
|||
} |
|||
|
|||
foreach (var ignoredType in _ignoredTypes) |
|||
{ |
|||
if (ignoredType.GetTypeInfo().IsAssignableFrom(property.PropertyType)) |
|||
{ |
|||
property.ShouldSerialize = instance => false; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return property; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace Volo.Abp.Auditing |
|||
{ |
|||
public class AuditingRuntimeIgnoreConverter : JsonConverter<Dictionary<string, object>> |
|||
{ |
|||
private readonly List<Type> _ignoredTypes; |
|||
|
|||
public AuditingRuntimeIgnoreConverter(List<Type> ignoredTypes) |
|||
{ |
|||
_ignoredTypes = ignoredTypes; |
|||
} |
|||
|
|||
public override Dictionary<string, object> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
throw new JsonException(); |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, Dictionary<string, object> value, JsonSerializerOptions options) |
|||
{ |
|||
var newDictionary = new Dictionary<string, object>(); |
|||
foreach (var item in value.Where(x => x.Value != null)) |
|||
{ |
|||
if (item.GetType().IsDefined(typeof(DisableAuditingAttribute), true) || |
|||
item.GetType().IsDefined(typeof(JsonIgnoreAttribute), true)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
if (_ignoredTypes.Any(x => x.IsInstanceOfType(item.Value))) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
newDictionary[item.Key] = item.Value; |
|||
} |
|||
|
|||
JsonSerializer.Serialize(writer, newDictionary); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace Volo.Abp.Domain.Entities |
|||
{ |
|||
public class EntityJsonConverter<TEntity, TKey> : JsonConverter<TEntity> |
|||
{ |
|||
public override TEntity Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
var jsonDocument = JsonDocument.ParseValue(ref reader); |
|||
var entity = (TEntity)JsonSerializer.Deserialize(jsonDocument.RootElement.GetRawText(), typeToConvert); |
|||
var idJsonElement = jsonDocument.RootElement.GetProperty(nameof(IEntity<object>.Id)); |
|||
|
|||
var id = JsonSerializer.Deserialize<TKey>(idJsonElement.GetRawText()); |
|||
if (id != null) |
|||
{ |
|||
EntityHelper.TrySetId(entity, id); |
|||
} |
|||
|
|||
return entity; |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, TEntity value, JsonSerializerOptions options) |
|||
{ |
|||
JsonSerializer.Serialize(writer, value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Json.Newtonsoft</AssemblyName> |
|||
<PackageId>Volo.Abp.Json.Newtonsoft</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,21 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Json.Microsoft; |
|||
using Volo.Abp.Json.Newtonsoft; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
[DependsOn(typeof(AbpJsonModule))] |
|||
public class AbpJsonNewtonsoftModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpNewtonsoftJsonSerializerOptions>(options => |
|||
{ |
|||
options.Converters.Add<AbpJsonIsoDateTimeConverter>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Json.Microsoft |
|||
{ |
|||
public class AbpJsonSerializer : IJsonSerializer, ITransientDependency |
|||
{ |
|||
protected AbpJsonSerializerOptions Options { get; } |
|||
|
|||
public AbpJsonSerializer(IOptions<AbpJsonSerializerOptions> options) |
|||
{ |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public string Serialize(object obj, bool camelCase = true, bool indented = false) |
|||
{ |
|||
return JsonSerializer.Serialize(obj, CreateJsonSerializerOptions(camelCase, indented)); |
|||
} |
|||
|
|||
public T Deserialize<T>(string jsonString, bool camelCase = true) |
|||
{ |
|||
return JsonSerializer.Deserialize<T>(jsonString, CreateJsonSerializerOptions(camelCase)); |
|||
} |
|||
|
|||
public object Deserialize(Type type, string jsonString, bool camelCase = true) |
|||
{ |
|||
return JsonSerializer.Deserialize(jsonString, type, CreateJsonSerializerOptions(camelCase)); |
|||
} |
|||
|
|||
protected virtual JsonSerializerOptions CreateJsonSerializerOptions(bool camelCase = true, bool indented = false) |
|||
{ |
|||
var settings = new JsonSerializerOptions(Options.JsonSerializerOptions); |
|||
|
|||
if (camelCase) |
|||
{ |
|||
settings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; |
|||
} |
|||
|
|||
if (indented) |
|||
{ |
|||
settings.WriteIndented = true; |
|||
} |
|||
|
|||
return settings; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Text.Json; |
|||
|
|||
namespace Volo.Abp.Json.Microsoft |
|||
{ |
|||
public class AbpJsonSerializerOptions |
|||
{ |
|||
public JsonSerializerOptions JsonSerializerOptions { get; } |
|||
|
|||
public AbpJsonSerializerOptions() |
|||
{ |
|||
//TODO:Defaults?
|
|||
//https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Core/src/JsonOptions.cs#L18
|
|||
//https://github.com/dotnet/runtime/blob/master/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerDefaults.cs
|
|||
|
|||
JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Json.Microsoft.JsonConverters; |
|||
|
|||
namespace Volo.Abp.Json.Microsoft |
|||
{ |
|||
public class AbpJsonSerializerOptionsSetup : IConfigureOptions<AbpJsonSerializerOptions> |
|||
{ |
|||
protected IServiceProvider ServiceProvider { get; } |
|||
|
|||
public AbpJsonSerializerOptionsSetup(IServiceProvider serviceProvider) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
|
|||
public void Configure(AbpJsonSerializerOptions options) |
|||
{ |
|||
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService<AbpDateTimeConverter>()); |
|||
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Timing; |
|||
|
|||
namespace Volo.Abp.Json.Microsoft.JsonConverters |
|||
{ |
|||
public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependency |
|||
{ |
|||
private readonly IClock _clock; |
|||
private readonly AbpJsonOptions _options; |
|||
|
|||
public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions) |
|||
{ |
|||
_clock = clock; |
|||
_options = abpJsonOptions.Value; |
|||
} |
|||
|
|||
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
return _clock.Normalize(reader.GetDateTime()); |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) |
|||
{ |
|||
if (_options.DefaultDateTimeFormat.IsNullOrWhiteSpace()) |
|||
{ |
|||
writer.WriteStringValue(_clock.Normalize(value)); |
|||
} |
|||
else |
|||
{ |
|||
writer.WriteStringValue(_clock.Normalize(value).ToString(_options.DefaultDateTimeFormat)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Timing; |
|||
|
|||
namespace Volo.Abp.Json.Microsoft.JsonConverters |
|||
{ |
|||
public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransientDependency |
|||
{ |
|||
private readonly IClock _clock; |
|||
private readonly AbpJsonOptions _options; |
|||
|
|||
public AbpNullableDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions) |
|||
{ |
|||
_clock = clock; |
|||
_options = abpJsonOptions.Value; |
|||
} |
|||
|
|||
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
if (reader.TryGetDateTime(out var dateTime)) |
|||
{ |
|||
return _clock.Normalize(dateTime); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
writer.WriteNullValue(); |
|||
} |
|||
else |
|||
{ |
|||
if (_options.DefaultDateTimeFormat.IsNullOrWhiteSpace()) |
|||
{ |
|||
writer.WriteStringValue(_clock.Normalize(value.Value)); |
|||
} |
|||
else |
|||
{ |
|||
writer.WriteStringValue(_clock.Normalize(value.Value).ToString(_options.DefaultDateTimeFormat)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace Volo.Abp.Json.Microsoft.JsonConverters |
|||
{ |
|||
public class ObjectToInferredTypesConverter : JsonConverter<object> |
|||
{ |
|||
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
if (reader.TokenType == JsonTokenType.True) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
if (reader.TokenType == JsonTokenType.False) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (reader.TokenType == JsonTokenType.Number) |
|||
{ |
|||
if (reader.TryGetInt64(out var l)) |
|||
{ |
|||
return l; |
|||
} |
|||
|
|||
return reader.GetDouble(); |
|||
} |
|||
|
|||
if (reader.TokenType == JsonTokenType.String) |
|||
{ |
|||
if (reader.TryGetDateTime(out var datetime)) |
|||
{ |
|||
return datetime; |
|||
} |
|||
|
|||
return reader.GetString(); |
|||
} |
|||
|
|||
// Use JsonElement as fallback.
|
|||
// Newtonsoft uses JArray or JObject.
|
|||
using (var document = JsonDocument.ParseValue(ref reader)) |
|||
{ |
|||
return document.RootElement.Clone(); |
|||
} |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options) |
|||
{ |
|||
throw new InvalidOperationException("Should not get here."); |
|||
} |
|||
} |
|||
} |
|||
@ -1,52 +1,27 @@ |
|||
using System; |
|||
using System.Reflection; |
|||
using System.Text; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Serialization; |
|||
using System.Text.Json; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Json; |
|||
|
|||
namespace Volo.Abp.Domain.Repositories.MemoryDb |
|||
{ |
|||
public class Utf8JsonMemoryDbSerializer : IMemoryDbSerializer, ITransientDependency |
|||
{ |
|||
private static readonly JsonSerializerSettings MemoryDbSerializerSettings; |
|||
protected Utf8JsonMemoryDbSerializerOptions Options { get; } |
|||
|
|||
static Utf8JsonMemoryDbSerializer() |
|||
public Utf8JsonMemoryDbSerializer(IOptions<Utf8JsonMemoryDbSerializerOptions> options) |
|||
{ |
|||
MemoryDbSerializerSettings = new JsonSerializerSettings |
|||
{ |
|||
ContractResolver = new ResolverWithPrivateSetters(), |
|||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor |
|||
}; |
|||
Options = options.Value; |
|||
} |
|||
|
|||
byte[] IMemoryDbSerializer.Serialize(object obj) |
|||
{ |
|||
var jsonString = JsonConvert.SerializeObject(obj, MemoryDbSerializerSettings); |
|||
return Encoding.UTF8.GetBytes(jsonString); |
|||
return JsonSerializer.SerializeToUtf8Bytes(obj, Options.JsonSerializerOptions); |
|||
} |
|||
|
|||
public object Deserialize(byte[] value, Type type) |
|||
{ |
|||
var jsonString = Encoding.UTF8.GetString(value); |
|||
return JsonConvert.DeserializeObject(jsonString, type, MemoryDbSerializerSettings); |
|||
} |
|||
|
|||
public class ResolverWithPrivateSetters : DefaultContractResolver |
|||
{ |
|||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) |
|||
{ |
|||
var prop = base.CreateProperty(member, memberSerialization); |
|||
if (prop.Writable) |
|||
{ |
|||
return prop; |
|||
} |
|||
|
|||
prop.Writable = member.As<PropertyInfo>()?.GetSetMethod(true) != null; |
|||
|
|||
return prop; |
|||
} |
|||
return JsonSerializer.Deserialize(value, type, Options.JsonSerializerOptions); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,14 @@ |
|||
using System.Text.Json; |
|||
|
|||
namespace Volo.Abp.Domain.Repositories.MemoryDb |
|||
{ |
|||
public class Utf8JsonMemoryDbSerializerOptions |
|||
{ |
|||
public JsonSerializerOptions JsonSerializerOptions { get; } |
|||
|
|||
public Utf8JsonMemoryDbSerializerOptions() |
|||
{ |
|||
JsonSerializerOptions = new JsonSerializerOptions(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace Volo.Abp.FeatureManagement.JsonConverters |
|||
{ |
|||
public class LocalizableStringInfoJsonConverter : JsonConverter<LocalizableStringInfo> |
|||
{ |
|||
public override LocalizableStringInfo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
var rootElement = JsonDocument.ParseValue(ref reader).RootElement; |
|||
return new LocalizableStringInfo( |
|||
rootElement.GetProperty("ResourceName").GetString(), |
|||
rootElement.GetProperty("Name").GetString() |
|||
); |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, LocalizableStringInfo value, JsonSerializerOptions options) |
|||
{ |
|||
JsonSerializer.Serialize(writer, value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace Volo.Abp.FeatureManagement.JsonConverters |
|||
{ |
|||
public class SelectionStringValueItemJsonConverter : JsonConverter<ISelectionStringValueItem> |
|||
{ |
|||
public override ISelectionStringValueItem Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
var rootElement = JsonDocument.ParseValue(ref reader).RootElement; |
|||
|
|||
var jsonSerializerOptions = new JsonSerializerOptions(); |
|||
jsonSerializerOptions.Converters.Add(new LocalizableStringInfoJsonConverter()); |
|||
|
|||
return new LocalizableSelectionStringValueItem |
|||
{ |
|||
Value = rootElement.GetProperty("Value").GetString(), |
|||
DisplayText = JsonSerializer.Deserialize<LocalizableStringInfo>(rootElement.GetProperty("DisplayText").GetRawText(), jsonSerializerOptions) |
|||
}; |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, ISelectionStringValueItem value, JsonSerializerOptions options) |
|||
{ |
|||
if (value.GetType() == typeof(LocalizableStringInfo)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (LocalizableSelectionStringValueItem)value); |
|||
} |
|||
else |
|||
{ |
|||
throw new JsonException("Unknown ISelectionStringValueItem type!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace Volo.Abp.FeatureManagement.JsonConverters |
|||
{ |
|||
public class SelectionStringValueItemSourceJsonConverter : JsonConverter<ISelectionStringValueItemSource> |
|||
{ |
|||
public override ISelectionStringValueItemSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
var rootElement = JsonDocument.ParseValue(ref reader).RootElement; |
|||
var jsonSerializerOptions = new JsonSerializerOptions(); |
|||
jsonSerializerOptions.Converters.Add(new SelectionStringValueItemJsonConverter()); |
|||
|
|||
var selectionStringValueItem = |
|||
JsonSerializer.Deserialize<List<LocalizableSelectionStringValueItem>>(rootElement.GetProperty("Items").GetRawText(), jsonSerializerOptions) ?? |
|||
new List<LocalizableSelectionStringValueItem>(); |
|||
|
|||
return new StaticSelectionStringValueItemSource(selectionStringValueItem.ToArray()); |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, ISelectionStringValueItemSource value, JsonSerializerOptions options) |
|||
{ |
|||
if (value.GetType() == typeof(StaticSelectionStringValueItemSource)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (StaticSelectionStringValueItemSource)value); |
|||
} |
|||
else |
|||
{ |
|||
throw new JsonException("Unknown ISelectionStringValueItemSource type!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
using System; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace Volo.Abp.FeatureManagement.JsonConverters |
|||
{ |
|||
public class StringValueTypeJsonConverter : JsonConverter<IStringValueType> |
|||
{ |
|||
public override IStringValueType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
var rootElement = JsonDocument.ParseValue(ref reader).RootElement; |
|||
var jsonSerializerOptions = new JsonSerializerOptions(); |
|||
jsonSerializerOptions.Converters.Add(new ValueValidatorJsonConverter()); |
|||
jsonSerializerOptions.Converters.Add(new SelectionStringValueItemSourceJsonConverter()); |
|||
|
|||
var name = rootElement.GetProperty("Name").GetString(); |
|||
return name switch |
|||
{ |
|||
"SelectionStringValueType" => JsonSerializer.Deserialize<SelectionStringValueType>(rootElement.GetRawText(), jsonSerializerOptions), |
|||
"FreeTextStringValueType" => JsonSerializer.Deserialize<FreeTextStringValueType>(rootElement.GetRawText(), jsonSerializerOptions), |
|||
"ToggleStringValueType" => JsonSerializer.Deserialize<ToggleStringValueType>(rootElement.GetRawText(), jsonSerializerOptions), |
|||
_ => throw new ArgumentException($"{nameof(IStringValueType)} named {name} was not found!") |
|||
}; |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, IStringValueType value, JsonSerializerOptions options) |
|||
{ |
|||
if (value.GetType() == typeof(FreeTextStringValueType)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (FreeTextStringValueType)value); |
|||
} |
|||
else if (value.GetType() == typeof(SelectionStringValueType)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (SelectionStringValueType)value); |
|||
} |
|||
else if (value.GetType() == typeof(ToggleStringValueType)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (ToggleStringValueType)value); |
|||
} |
|||
else |
|||
{ |
|||
throw new JsonException("Unknown IStringValueType type!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp.Json.Microsoft.JsonConverters; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace Volo.Abp.FeatureManagement.JsonConverters |
|||
{ |
|||
public class ValueValidatorJsonConverter : JsonConverter<IValueValidator> |
|||
{ |
|||
public override IValueValidator Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|||
{ |
|||
var rootElement = JsonDocument.ParseValue(ref reader).RootElement; |
|||
var valueValidator = CreateValueValidatorByName(rootElement.GetProperty("Name").GetString()); |
|||
|
|||
var deserializeOptions = new JsonSerializerOptions(); |
|||
deserializeOptions.Converters.Add(new ObjectToInferredTypesConverter()); |
|||
var properties = JsonSerializer.Deserialize<IDictionary<string, object>>(rootElement.GetProperty("Properties").GetRawText(), deserializeOptions); |
|||
if (properties != null && properties.Any()) |
|||
{ |
|||
foreach (var property in properties) |
|||
{ |
|||
valueValidator.Properties[property.Key] = property.Value; |
|||
} |
|||
} |
|||
|
|||
return valueValidator; |
|||
} |
|||
|
|||
public override void Write(Utf8JsonWriter writer, IValueValidator value, JsonSerializerOptions options) |
|||
{ |
|||
if (value.GetType() == typeof(AlwaysValidValueValidator)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (AlwaysValidValueValidator)value); |
|||
} |
|||
else if (value.GetType() == typeof(BooleanValueValidator)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (BooleanValueValidator)value); |
|||
} |
|||
else if (value.GetType() == typeof(NumericValueValidator)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (NumericValueValidator)value); |
|||
} |
|||
else if (value.GetType() == typeof(StringValueValidator)) |
|||
{ |
|||
JsonSerializer.Serialize(writer, (StringValueValidator)value); |
|||
} |
|||
else |
|||
{ |
|||
throw new JsonException("Unknown IValueValidator type!"); |
|||
} |
|||
} |
|||
|
|||
protected virtual IValueValidator CreateValueValidatorByName(string name) |
|||
{ |
|||
return name switch |
|||
{ |
|||
"NULL" => new AlwaysValidValueValidator(), |
|||
"BOOLEAN" => new BooleanValueValidator(), |
|||
"NUMERIC" => new NumericValueValidator(), |
|||
"STRING" => new StringValueValidator(), |
|||
_ => throw new ArgumentException($"{nameof(IValueValidator)} named {name} was not found!") |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -1,90 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Linq; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace Volo.Abp.FeatureManagement |
|||
{ |
|||
public class StringValueTypeJsonConverter : JsonConverter, ITransientDependency |
|||
{ |
|||
public override bool CanWrite => false; |
|||
|
|||
public override bool CanConvert(Type objectType) |
|||
{ |
|||
return objectType == typeof(IStringValueType); |
|||
} |
|||
|
|||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) |
|||
{ |
|||
throw new NotImplementedException("This method should not be called to write (since CanWrite is false)."); |
|||
} |
|||
|
|||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) |
|||
{ |
|||
if (reader.TokenType != JsonToken.StartObject) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var jsonObject = JObject.Load(reader); |
|||
|
|||
var stringValue = CreateStringValueTypeByName(jsonObject, jsonObject["name"].ToString()); |
|||
foreach (var o in serializer.Deserialize<Dictionary<string, object>>( |
|||
new JsonTextReader(new StringReader(jsonObject["properties"].ToString())))) |
|||
{ |
|||
stringValue[o.Key] = o.Value; |
|||
} |
|||
|
|||
stringValue.Validator = CreateValueValidatorByName(jsonObject["validator"], jsonObject["validator"]["name"].ToString()); |
|||
foreach (var o in serializer.Deserialize<Dictionary<string, object>>( |
|||
new JsonTextReader(new StringReader(jsonObject["validator"]["properties"].ToString())))) |
|||
{ |
|||
stringValue.Validator[o.Key] = o.Value; |
|||
} |
|||
|
|||
return stringValue; |
|||
} |
|||
|
|||
protected virtual IStringValueType CreateStringValueTypeByName(JObject jObject, string name) |
|||
{ |
|||
if (name == "SelectionStringValueType") |
|||
{ |
|||
var selectionStringValueType = new SelectionStringValueType(); |
|||
if (jObject["itemSource"].HasValues) |
|||
{ |
|||
selectionStringValueType.ItemSource = new StaticSelectionStringValueItemSource(jObject["itemSource"]["items"] |
|||
.Select(item => new LocalizableSelectionStringValueItem() |
|||
{ |
|||
Value = item["value"].ToString(), |
|||
DisplayText = new LocalizableStringInfo(item["displayText"]["resourceName"].ToString(), item["displayText"]["name"].ToString()) |
|||
}).ToArray()); |
|||
} |
|||
|
|||
return selectionStringValueType; |
|||
} |
|||
|
|||
return name switch |
|||
{ |
|||
"FreeTextStringValueType" => new FreeTextStringValueType(), |
|||
"ToggleStringValueType" => new ToggleStringValueType(), |
|||
_ => throw new ArgumentException($"{nameof(IStringValueType)} named {name} was not found!") |
|||
}; |
|||
} |
|||
|
|||
protected virtual IValueValidator CreateValueValidatorByName(JToken jObject, string name) |
|||
{ |
|||
return name switch |
|||
{ |
|||
"NULL" => new AlwaysValidValueValidator(), |
|||
"BOOLEAN" => new BooleanValueValidator(), |
|||
"NUMERIC" => new NumericValueValidator(), |
|||
"STRING" => new StringValueValidator(), |
|||
_ => throw new ArgumentException($"{nameof(IValueValidator)} named {name} was not found!") |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue