Merge pull request #10811 from abpframework/auto-merge/rel-5-0/670

Merge branch dev with rel-5.0
pull/10821/head^2
maliming 4 years ago committed by GitHub
commit c620c3c4db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -714,4 +714,4 @@ To add these functionalities, update the `Viewer.cshtml` file under the `Pages/R
## Source Code
- You can download the source code from [here](https://github.com/gterdem/abp-devexpress-reporting-sample).
- You can download the source code from [here](https://github.com/abpframework/abp-samples/tree/master/DevExtreme-Reports-Mvc).

@ -29,6 +29,5 @@ public class AbpJsonOptionsSetup : IConfigureOptions<JsonOptions>
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory());
}
}

@ -19,10 +19,16 @@ public class AbpJsonValueConverter<TPropertyType> : ValueConverter<TPropertyType
return JsonSerializer.Serialize(d);
}
private static readonly JsonSerializerOptions DeserializeOptions = new JsonSerializerOptions()
{
Converters =
{
new ObjectToInferredTypesConverter()
}
};
private static TPropertyType DeserializeObject(string s)
{
var deserializeOptions = new JsonSerializerOptions();
deserializeOptions.Converters.Add(new ObjectToInferredTypesConverter());
return JsonSerializer.Deserialize<TPropertyType>(s, deserializeOptions);
return JsonSerializer.Deserialize<TPropertyType>(s, DeserializeOptions);
}
}

@ -41,6 +41,14 @@ public class ExtraPropertiesValueConverter : ValueConverter<ExtraPropertyDiction
return JsonSerializer.Serialize(copyDictionary);
}
private static readonly JsonSerializerOptions DeserializeOptions = new JsonSerializerOptions()
{
Converters =
{
new ObjectToInferredTypesConverter()
}
};
private static ExtraPropertyDictionary DeserializeObject(string extraPropertiesAsJson, Type entityType)
{
if (extraPropertiesAsJson.IsNullOrEmpty() || extraPropertiesAsJson == "{}")
@ -48,11 +56,8 @@ public class ExtraPropertiesValueConverter : ValueConverter<ExtraPropertyDiction
return new ExtraPropertyDictionary();
}
var deserializeOptions = new JsonSerializerOptions();
deserializeOptions.Converters.Add(new ObjectToInferredTypesConverter());
var dictionary = JsonSerializer.Deserialize<ExtraPropertyDictionary>(extraPropertiesAsJson, deserializeOptions) ??
new ExtraPropertyDictionary();
var dictionary = JsonSerializer.Deserialize<ExtraPropertyDictionary>(extraPropertiesAsJson, DeserializeOptions) ??
new ExtraPropertyDictionary();
if (entityType != null)
{

@ -90,6 +90,11 @@ public class ApiDescriptionFinder : IApiDescriptionFinder, ITransientDependency
return await Cache.GetAsync(baseUrl, () => GetApiDescriptionFromServerAsync(client, baseUrl));
}
private static readonly JsonSerializerOptions DeserializeOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
protected virtual async Task<ApplicationApiDescriptionModel> GetApiDescriptionFromServerAsync(
HttpClient client,
string baseUrl)
@ -113,10 +118,7 @@ public class ApiDescriptionFinder : IApiDescriptionFinder, ITransientDependency
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApplicationApiDescriptionModel>(content, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
var result = JsonSerializer.Deserialize<ApplicationApiDescriptionModel>(content, DeserializeOptions);
return result;
}

@ -25,7 +25,6 @@ public class AbpSystemTextJsonSerializerOptionsSetup : IConfigureOptions<AbpSyst
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory());
// If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
options.JsonSerializerOptions.Encoder ??= JavaScriptEncoder.UnsafeRelaxedJsonEscaping;

@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Text.Json;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -39,20 +40,25 @@ public class AbpSystemTextJsonSerializerProvider : IJsonSerializerProvider, ITra
return JsonSerializer.Deserialize(jsonString, type, CreateJsonSerializerOptions(camelCase));
}
private readonly ConcurrentDictionary<string, JsonSerializerOptions> JsonSerializerOptionsCache = new ConcurrentDictionary<string, JsonSerializerOptions>();
protected virtual JsonSerializerOptions CreateJsonSerializerOptions(bool camelCase = true, bool indented = false)
{
var settings = new JsonSerializerOptions(Options.JsonSerializerOptions);
if (camelCase)
return JsonSerializerOptionsCache.GetOrAdd($"default{camelCase}{indented}", _ =>
{
settings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
}
var settings = new JsonSerializerOptions(Options.JsonSerializerOptions);
if (indented)
{
settings.WriteIndented = true;
}
if (camelCase)
{
settings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
}
if (indented)
{
settings.WriteIndented = true;
}
return settings;
return settings;
});
}
}

@ -1,54 +0,0 @@
using System;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Volo.Abp.Data;
namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpHasExtraPropertiesJsonConverter<T> : JsonConverter<T>
where T : IHasExtraProperties
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, x => x == this);
var converterFactory = newOptions.Converters.FirstOrDefault(x => x is AbpHasExtraPropertiesJsonConverterFactory).As<AbpHasExtraPropertiesJsonConverterFactory>();
var newConverterFactory = new AbpHasExtraPropertiesJsonConverterFactory();
if (converterFactory != null)
{
newOptions.Converters.Remove(converterFactory);
newConverterFactory.AddExcludeTypes(converterFactory.GetExcludeTypes().ToArray());
}
newConverterFactory.AddExcludeTypes(typeToConvert);
newOptions.Converters.Add(newConverterFactory);
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
if (rootElement.ValueKind == JsonValueKind.Object)
{
var extensibleObject = rootElement.Deserialize<T>(newOptions);
var extraPropertiesJsonProperty = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals(nameof(IHasExtraProperties.ExtraProperties), StringComparison.OrdinalIgnoreCase));
if (extraPropertiesJsonProperty.Value.ValueKind == JsonValueKind.Object)
{
var extraPropertyDictionary = extraPropertiesJsonProperty.Value.Deserialize(typeof(ExtraPropertyDictionary), newOptions);
ObjectHelper.TrySetProperty(extensibleObject, x => x.ExtraProperties, () => extraPropertyDictionary);
}
return extensibleObject;
}
throw new JsonException("RootElement's ValueKind is not Object!");
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(AbpHasExtraPropertiesJsonConverterFactory));
JsonSerializer.Serialize(writer, value, newOptions);
}
}

@ -1,64 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Volo.Abp.Data;
namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpHasExtraPropertiesJsonConverterFactory : JsonConverterFactory
{
private static readonly ConcurrentDictionary<Type, bool> CachedTypes = new ConcurrentDictionary<Type, bool>();
private readonly List<Type> _excludeTypes = new List<Type>();
public virtual AbpHasExtraPropertiesJsonConverterFactory AddExcludeTypes(params Type[] excludeTypes)
{
_excludeTypes.AddIfNotContains(excludeTypes);
return this;
}
public virtual IReadOnlyList<Type> GetExcludeTypes()
{
return _excludeTypes.ToImmutableList();
}
public override bool CanConvert(Type typeToConvert)
{
if (_excludeTypes.Contains(typeToConvert))
{
return false;
}
//Only for private or protected ExtraProperties.
if (typeof(IHasExtraProperties).IsAssignableFrom(typeToConvert))
{
return CachedTypes.GetOrAdd(typeToConvert, type =>
{
var property = type.GetProperty(nameof(IHasExtraProperties.ExtraProperties));
if (property != null)
{
var setMethod = property.GetSetMethod(true);
return setMethod != null && (setMethod.IsPrivate || setMethod.IsFamily);
}
return false;
});
}
return false;
}
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter)Activator.CreateInstance(
typeof(AbpHasExtraPropertiesJsonConverter<>).MakeGenericType(typeToConvert),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
null,
culture: null)!;
}
}

@ -8,6 +8,8 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpStringToBooleanConverter : JsonConverter<bool>
{
private JsonSerializerOptions _writeJsonSerializerOptions;
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
@ -29,8 +31,9 @@ public class AbpStringToBooleanConverter : JsonConverter<bool>
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this);
var entityConverter = (JsonConverter<bool>)newOptions.GetConverter(typeof(bool));
entityConverter.Write(writer, value, newOptions);
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
var entityConverter = (JsonConverter<bool>)_writeJsonSerializerOptions.GetConverter(typeof(bool));
entityConverter.Write(writer, value, _writeJsonSerializerOptions);
}
}

@ -10,6 +10,10 @@ public class AbpStringToEnumConverter<T> : JsonConverter<T>
{
private readonly JsonStringEnumConverter _innerJsonStringEnumConverter;
private JsonSerializerOptions _readJsonSerializerOptions;
private JsonSerializerOptions _writeJsonSerializerOptions;
public AbpStringToEnumConverter()
: this(namingPolicy: null, allowIntegerValues: true)
{
@ -28,20 +32,20 @@ public class AbpStringToEnumConverter<T> : JsonConverter<T>
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(AbpStringToEnumFactory));
_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(AbpStringToEnumFactory),
_innerJsonStringEnumConverter.CreateConverter(typeToConvert, options));
newOptions.Converters.Add(_innerJsonStringEnumConverter.CreateConverter(typeToConvert, newOptions));
return JsonSerializer.Deserialize<T>(ref reader, newOptions);
return JsonSerializer.Deserialize<T>(ref reader, _readJsonSerializerOptions);
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, x =>
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(AbpStringToEnumFactory));
JsonSerializer.Serialize(writer, value, newOptions);
JsonSerializer.Serialize(writer, value, _writeJsonSerializerOptions);
}
}

@ -24,6 +24,14 @@ public static class JsonLocalizationDictionaryBuilder
}
}
private static readonly JsonSerializerOptions DeserializeOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true
};
/// <summary>
/// Builds an <see cref="JsonLocalizationDictionaryBuilder" /> from given json string.
/// </summary>
@ -33,15 +41,7 @@ public static class JsonLocalizationDictionaryBuilder
JsonLocalizationFile jsonFile;
try
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true
};
jsonFile = JsonSerializer.Deserialize<JsonLocalizationFile>(jsonString, options);
jsonFile = JsonSerializer.Deserialize<JsonLocalizationFile>(jsonString, DeserializeOptions);
}
catch (JsonException ex)
{

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Volo.Abp.Data;
using Volo.Abp.DynamicProxy;
@ -9,6 +10,7 @@ namespace Volo.Abp.ObjectExtending;
[Serializable]
public class ExtensibleObject : IHasExtraProperties, IValidatableObject
{
[JsonInclude]
public ExtraPropertyDictionary ExtraProperties { get; protected set; }
public ExtensibleObject()

@ -0,0 +1,54 @@
using System.Text.Json;
using Shouldly;
using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Xunit;
namespace Volo.Abp.Json
{
public class AbpStringToBoolean_Tests
{
[Fact]
public void Test_Read()
{
var options = new JsonSerializerOptions()
{
Converters =
{
new AbpStringToBooleanConverter()
}
};
var testClass = JsonSerializer.Deserialize<TestClass>("{\"Enabled\": \"TrUe\"}", options);
testClass.ShouldNotBeNull();
testClass.Enabled.ShouldBe(true);
testClass = JsonSerializer.Deserialize<TestClass>("{\"Enabled\": true}", options);
testClass.ShouldNotBeNull();
testClass.Enabled.ShouldBe(true);
}
[Fact]
public void Test_Write()
{
var options = new JsonSerializerOptions()
{
Converters =
{
new AbpStringToBooleanConverter()
}
};
var testClassJson = JsonSerializer.Serialize(new TestClass()
{
Enabled = true
});
testClassJson.ShouldBe("{\"Enabled\":true}");
}
class TestClass
{
public bool Enabled { get; set; }
}
}
}

@ -0,0 +1,55 @@
using System;
using System.Text.Json;
using Shouldly;
using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Xunit;
namespace Volo.Abp.Json
{
public class AbpStringToEnum_Tests
{
[Fact]
public void Test_Read()
{
var options = new JsonSerializerOptions()
{
Converters =
{
new AbpStringToEnumFactory()
}
};
var testClass = JsonSerializer.Deserialize<TestClass>("{\"Day\": \"Monday\"}", options);
testClass.ShouldNotBeNull();
testClass.Day.ShouldBe(DayOfWeek.Monday);
testClass = JsonSerializer.Deserialize<TestClass>("{\"Day\": 1}", options);
testClass.ShouldNotBeNull();
testClass.Day.ShouldBe(DayOfWeek.Monday);
}
[Fact]
public void Test_Write()
{
var options = new JsonSerializerOptions()
{
Converters =
{
new AbpStringToEnumFactory()
}
};
var testClassJson = JsonSerializer.Serialize(new TestClass()
{
Day = DayOfWeek.Monday
});
testClassJson.ShouldBe("{\"Day\":1}");
}
class TestClass
{
public DayOfWeek Day { get; set; }
}
}
}

@ -174,8 +174,7 @@ public class AbpSystemTextJsonSerializerProvider_Tests : AbpSystemTextJsonSerial
{
var json = "{\"name\":\"test\",\"extraProperties\":null}";
var extensibleObject = JsonSerializer.Deserialize<TestExtensibleObjectClass>(json);
extensibleObject.ExtraProperties.ShouldNotBeNull();
extensibleObject.ExtraProperties.ShouldBeEmpty();
extensibleObject.ExtraProperties.ShouldBeNull();
}
[Fact]

@ -7,11 +7,11 @@ using Xunit;
namespace Volo.Abp.Json;
public class AbpHasExtraPropertiesJsonConverter_Tests : AbpJsonTestBase
public class ExtensibleObject_Tests: AbpJsonTestBase
{
private readonly IJsonSerializer _jsonSerializer;
public AbpHasExtraPropertiesJsonConverter_Tests()
public ExtensibleObject_Tests()
{
_jsonSerializer = GetRequiredService<IJsonSerializer>();
}
@ -60,16 +60,53 @@ public class AbpHasExtraPropertiesJsonConverter_Tests : AbpJsonTestBase
fooDto.BarDtos.First().Name.ShouldBe("new-bar-dto");
fooDto.BarDtos.First().GetProperty("bar").ShouldBe("new-bar-value");
}
[Fact]
public void SelfReference_Test()
{
var parentNodeDto = new NodeDto
{
Name = "parentNode",
};
parentNodeDto.SetProperty("node", "parent-value");
var nodeDto = new NodeDto
{
Name = "node",
Parent = parentNodeDto
};
nodeDto.SetProperty("node", "node-value");
var json = _jsonSerializer.Serialize(nodeDto);
nodeDto = _jsonSerializer.Deserialize<NodeDto>(json);
nodeDto.ShouldNotBeNull();
nodeDto.Name.ShouldBe("node");
nodeDto.GetProperty("node").ShouldBe("node-value");
nodeDto.Parent.ShouldNotBeNull();
nodeDto.Parent.Name.ShouldBe("parentNode");
nodeDto.Parent.GetProperty("node").ShouldBe("parent-value");
}
}
public class FooDto : ExtensibleObject
class FooDto : ExtensibleObject
{
public string Name { get; set; }
public List<BarDto> BarDtos { get; set; }
}
public class BarDto : ExtensibleObject
class BarDto : ExtensibleObject
{
public string Name { get; set; }
public FooDto FooDto { get; set; }
}
class NodeDto : ExtensibleObject
{
public string Name { get; set; }
public NodeDto Parent { get; set; }
}

@ -8,6 +8,8 @@ namespace Volo.Abp.MemoryDb.JsonConverters;
public class EntityJsonConverter<TEntity, TKey> : JsonConverter<TEntity>
where TEntity : Entity<TKey>
{
private JsonSerializerOptions _writeJsonSerializerOptions;
public override TEntity Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var jsonDocument = JsonDocument.ParseValue(ref reader);
@ -32,7 +34,7 @@ public class EntityJsonConverter<TEntity, TKey> : JsonConverter<TEntity>
public override void Write(Utf8JsonWriter writer, TEntity value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, newOptions);
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, _writeJsonSerializerOptions);
}
}

@ -8,6 +8,10 @@ namespace Volo.Abp.FeatureManagement.JsonConverters;
public class SelectionStringValueItemSourceJsonConverter : JsonConverter<ISelectionStringValueItemSource>
{
private JsonSerializerOptions _readJsonSerializerOptions;
private JsonSerializerOptions _writeJsonSerializerOptions;
public override ISelectionStringValueItemSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
@ -16,10 +20,10 @@ public class SelectionStringValueItemSourceJsonConverter : JsonConverter<ISelect
if (itemsJsonProperty.Value.ValueKind == JsonValueKind.Array)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this);
_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
var selectionStringValueItem =
itemsJsonProperty.Value.Deserialize<LocalizableSelectionStringValueItem[]>(newOptions) ??
itemsJsonProperty.Value.Deserialize<LocalizableSelectionStringValueItem[]>(_readJsonSerializerOptions) ??
Array.Empty<LocalizableSelectionStringValueItem>();
return new StaticSelectionStringValueItemSource(selectionStringValueItem.As<ISelectionStringValueItem[]>());
@ -28,10 +32,9 @@ public class SelectionStringValueItemSourceJsonConverter : JsonConverter<ISelect
throw new JsonException($"Can't to get the {nameof(ISelectionStringValueItemSource.Items)} property of {nameof(ISelectionStringValueItemSource)}!");
}
public override void Write(Utf8JsonWriter writer, ISelectionStringValueItemSource value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, value.GetType(), newOptions);
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, value.GetType(), _writeJsonSerializerOptions);
}
}

@ -8,6 +8,10 @@ namespace Volo.Abp.FeatureManagement.JsonConverters;
public class StringValueTypeJsonConverter : JsonConverter<IStringValueType>
{
private JsonSerializerOptions _readJsonSerializerOptions;
private JsonSerializerOptions _writeJsonSerializerOptions;
public override IStringValueType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
@ -17,14 +21,13 @@ public class StringValueTypeJsonConverter : JsonConverter<IStringValueType>
{
var name = nameJsonProperty.Value.GetString();
var newOptions = JsonSerializerOptionsHelper.Create(options, this, new ValueValidatorJsonConverter(),
new SelectionStringValueItemSourceJsonConverter());
_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this, new ValueValidatorJsonConverter(), new SelectionStringValueItemSourceJsonConverter());
return name switch
{
"SelectionStringValueType" => rootElement.Deserialize<SelectionStringValueType>(newOptions),
"FreeTextStringValueType" => rootElement.Deserialize<FreeTextStringValueType>(newOptions),
"ToggleStringValueType" => rootElement.Deserialize<ToggleStringValueType>(newOptions),
"SelectionStringValueType" => rootElement.Deserialize<SelectionStringValueType>(_readJsonSerializerOptions),
"FreeTextStringValueType" => rootElement.Deserialize<FreeTextStringValueType>(_readJsonSerializerOptions),
"ToggleStringValueType" => rootElement.Deserialize<ToggleStringValueType>(_readJsonSerializerOptions),
_ => throw new ArgumentException($"{nameof(IStringValueType)} named {name} was not found!")
};
}
@ -34,7 +37,7 @@ public class StringValueTypeJsonConverter : JsonConverter<IStringValueType>
public override void Write(Utf8JsonWriter writer, IStringValueType value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, value.GetType(), newOptions);
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, value.GetType(), _writeJsonSerializerOptions);
}
}

@ -10,6 +10,10 @@ namespace Volo.Abp.FeatureManagement.JsonConverters;
public class ValueValidatorJsonConverter : JsonConverter<IValueValidator>
{
private JsonSerializerOptions _readJsonSerializerOptions;
private JsonSerializerOptions _writeJsonSerializerOptions;
public override IValueValidator Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
@ -22,8 +26,8 @@ public class ValueValidatorJsonConverter : JsonConverter<IValueValidator>
var propertiesJsonProperty = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals(nameof(IValueValidator.Properties), StringComparison.OrdinalIgnoreCase));
if (propertiesJsonProperty.Value.ValueKind == JsonValueKind.Object)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this, new ObjectToInferredTypesConverter());
var properties = propertiesJsonProperty.Value.Deserialize<IDictionary<string, object>>(newOptions);
_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this, new ObjectToInferredTypesConverter());
var properties = propertiesJsonProperty.Value.Deserialize<IDictionary<string, object>>(_readJsonSerializerOptions);
if (properties != null && properties.Any())
{
foreach (var property in properties)
@ -41,8 +45,8 @@ public class ValueValidatorJsonConverter : JsonConverter<IValueValidator>
public override void Write(Utf8JsonWriter writer, IValueValidator value, JsonSerializerOptions options)
{
var newOptions = JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, value.GetType(), newOptions);
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this);
JsonSerializer.Serialize(writer, value, value.GetType(), _writeJsonSerializerOptions);
}
protected virtual IValueValidator CreateValueValidatorByName(string name)

Loading…
Cancel
Save