Browse Source

Add AbpExtraPropertyDictionaryJsonConverter.

Resolve #6160
pull/6163/head
maliming 6 years ago
parent
commit
f69ccfa364
  1. 3
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs
  2. 1
      framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj
  3. 5
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs
  4. 39
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverter.cs
  5. 26
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverterFactory.cs
  6. 4
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
  7. 20
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs

3
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs

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

1
framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj

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

5
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs

@ -1,4 +1,4 @@
using System; using System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Json.SystemTextJson.JsonConverters; 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 AbpStringToEnumFactory());
options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter());
options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());
options.JsonSerializerOptions.Converters.Add(new AbpExtraPropertyDictionaryJsonConverterFactory());
} }
} }
} }

39
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverter.cs

@ -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);
}
}
}

26
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverterFactory.cs

@ -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)!;
}
}
}

4
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs

@ -51,7 +51,9 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters
public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options) 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);
} }
} }
} }

20
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs

@ -1,5 +1,7 @@
using Shouldly; using Shouldly;
using Volo.Abp.Data;
using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.ObjectExtending;
using Xunit; using Xunit;
namespace Volo.Abp.Json namespace Volo.Abp.Json
@ -78,6 +80,24 @@ namespace Volo.Abp.Json
newJson.ShouldBe("{\"name\":\"abp\",\"type\":2}"); 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 class FileWithBoolean
{ {
public string Name { get; set; } public string Name { get; set; }

Loading…
Cancel
Save