Add AbpExtraPropertyDictionaryJsonConverter.

Resolve #6160
pull/6163/head
maliming 5 years ago
parent 8605a73be2
commit f69ccfa364

@ -27,6 +27,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory());
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.Converters.Add(new AbpExtraPropertyDictionaryJsonConverterFactory());
}
}
}

@ -16,6 +16,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

@ -1,4 +1,4 @@
using System;
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Json.SystemTextJson.JsonConverters;
@ -21,6 +21,9 @@ namespace Volo.Abp.Json.SystemTextJson
options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory());
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.Converters.Add(new AbpExtraPropertyDictionaryJsonConverterFactory());
}
}
}

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.Json.SystemTextJson.JsonConverters
{
public class AbpExtraPropertyDictionaryJsonConverter<T> : JsonConverter<T>
where T : ExtensibleObject
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var newOptions = new JsonSerializerOptions(options);
newOptions.Converters.RemoveAll(x => x == this || x.GetType() == typeof(AbpExtraPropertyDictionaryJsonConverterFactory));
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
var extensibleObject = JsonSerializer.Deserialize<T>(rootElement.GetRawText(), newOptions);
var extraProperties = rootElement.EnumerateObject().FirstOrDefault(x =>
x.Name.Equals(nameof(ExtensibleObject.ExtraProperties), StringComparison.OrdinalIgnoreCase))
.Value.GetRawText();
var extraPropertyDictionary = JsonSerializer.Deserialize(extraProperties, typeof(ExtraPropertyDictionary), newOptions);
ObjectHelper.TrySetProperty(extensibleObject, x => x.ExtraProperties, () => extraPropertyDictionary);
return extensibleObject;
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var newOptions = new JsonSerializerOptions(options);
newOptions.Converters.RemoveAll(x => x == this || x.GetType() == typeof(AbpExtraPropertyDictionaryJsonConverterFactory));
JsonSerializer.Serialize(writer, value, newOptions);
}
}
}

@ -0,0 +1,26 @@
using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.Json.SystemTextJson.JsonConverters
{
public class AbpExtraPropertyDictionaryJsonConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert == typeof(ExtensibleObject) || typeToConvert.IsSubclassOf(typeof(ExtensibleObject));
}
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter) Activator.CreateInstance(
typeof(AbpExtraPropertyDictionaryJsonConverter<>).MakeGenericType(typeToConvert),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
null,
culture: null)!;
}
}
}

@ -51,7 +51,9 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters
public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options)
{
throw new InvalidOperationException("Should not get here.");
var newOptions = new JsonSerializerOptions(options);
newOptions.Converters.Remove(this);
JsonSerializer.Serialize(writer, objectToWrite, newOptions);
}
}
}

@ -1,5 +1,7 @@
using Shouldly;
using Volo.Abp.Data;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.ObjectExtending;
using Xunit;
namespace Volo.Abp.Json
@ -78,6 +80,24 @@ namespace Volo.Abp.Json
newJson.ShouldBe("{\"name\":\"abp\",\"type\":2}");
}
[Fact]
public void Serialize_Deserialize_ExtensibleObject()
{
var json = "{\"name\":\"test\",\"extraProperties\":{\"One\":\"123\",\"Two\":456}}";
var extensibleObject = _jsonSerializer.Deserialize<TestExtensibleObjectClass>(json);
extensibleObject.GetProperty("One").ShouldBe("123");
extensibleObject.GetProperty("Two").ShouldBe(456);
var newJson = _jsonSerializer.Serialize(extensibleObject);
newJson.ShouldBe(json);
}
class TestExtensibleObjectClass : ExtensibleObject
{
public string Name { get; set; }
}
class FileWithBoolean
{
public string Name { get; set; }

Loading…
Cancel
Save