Skip to content

Commit 78005a5

Browse files
authored
Merge pull request #9626 from abpframework/maliming/ExtensibleObject
Supports nested ExtensibleObject classes.
2 parents c8be236 + 9604e4d commit 78005a5

File tree

3 files changed

+108
-3
lines changed

3 files changed

+108
-3
lines changed

framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,18 @@ public class AbpHasExtraPropertiesJsonConverter<T> : JsonConverter<T>
1111
{
1212
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
1313
{
14-
var newOptions = JsonSerializerOptionsHelper.Create(options, x =>
15-
x == this ||
16-
x.GetType() == typeof(AbpHasExtraPropertiesJsonConverterFactory));
14+
var newOptions = JsonSerializerOptionsHelper.Create(options, x => x == this);
15+
16+
var converterFactory = newOptions.Converters.FirstOrDefault(x => x is AbpHasExtraPropertiesJsonConverterFactory).As<AbpHasExtraPropertiesJsonConverterFactory>();
17+
var newConverterFactory = new AbpHasExtraPropertiesJsonConverterFactory();
18+
if (converterFactory != null)
19+
{
20+
newOptions.Converters.Remove(converterFactory);
21+
newConverterFactory.AddExcludeTypes(converterFactory.GetExcludeTypes().ToArray());
22+
}
23+
24+
newConverterFactory.AddExcludeTypes(typeToConvert);
25+
newOptions.Converters.Add(newConverterFactory);
1726

1827
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
1928
if (rootElement.ValueKind == JsonValueKind.Object)

framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverterFactory.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
4+
using System.Collections.Immutable;
35
using System.Reflection;
46
using System.Text.Json;
57
using System.Text.Json.Serialization;
@@ -11,8 +13,26 @@ public class AbpHasExtraPropertiesJsonConverterFactory : JsonConverterFactory
1113
{
1214
private static readonly ConcurrentDictionary<Type, bool> CachedTypes = new ConcurrentDictionary<Type, bool>();
1315

16+
private readonly List<Type> _excludeTypes = new List<Type>();
17+
18+
public virtual AbpHasExtraPropertiesJsonConverterFactory AddExcludeTypes(params Type[] excludeTypes)
19+
{
20+
_excludeTypes.AddIfNotContains(excludeTypes);
21+
return this;
22+
}
23+
24+
public virtual IReadOnlyList<Type> GetExcludeTypes()
25+
{
26+
return _excludeTypes.ToImmutableList();
27+
}
28+
1429
public override bool CanConvert(Type typeToConvert)
1530
{
31+
if (_excludeTypes.Contains(typeToConvert))
32+
{
33+
return false;
34+
}
35+
1636
//Only for private or protected ExtraProperties.
1737
if (typeof(IHasExtraProperties).IsAssignableFrom(typeToConvert))
1838
{
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Shouldly;
4+
using Volo.Abp.Data;
5+
using Volo.Abp.ObjectExtending;
6+
using Xunit;
7+
8+
namespace Volo.Abp.Json
9+
{
10+
public class AbpHasExtraPropertiesJsonConverter_Tests: AbpJsonTestBase
11+
{
12+
private readonly IJsonSerializer _jsonSerializer;
13+
14+
public AbpHasExtraPropertiesJsonConverter_Tests()
15+
{
16+
_jsonSerializer = GetRequiredService<IJsonSerializer>();
17+
}
18+
19+
[Fact]
20+
public void JsonConverter_Test()
21+
{
22+
var fooDto = new FooDto
23+
{
24+
Name = "foo-dto",
25+
BarDtos = new List<BarDto>()
26+
};
27+
fooDto.SetProperty("foo", "foo-value");
28+
29+
var barDto = new BarDto
30+
{
31+
Name = "bar-dto"
32+
};
33+
barDto.SetProperty("bar", "bar-value");
34+
fooDto.BarDtos.Add(barDto);
35+
36+
var json = _jsonSerializer.Serialize(fooDto);
37+
38+
fooDto = _jsonSerializer.Deserialize<FooDto>(json);
39+
fooDto.ShouldNotBeNull();
40+
fooDto.Name.ShouldBe("foo-dto");
41+
fooDto.GetProperty("foo").ShouldBe("foo-value");
42+
43+
fooDto.BarDtos.Count.ShouldBe(1);
44+
fooDto.BarDtos.First().Name.ShouldBe("bar-dto");
45+
fooDto.BarDtos.First().GetProperty("bar").ShouldBe("bar-value");
46+
47+
fooDto.Name = "new-foo-dto";
48+
fooDto.SetProperty("foo", "new-foo-value");
49+
fooDto.BarDtos.First().Name = "new-bar-dto";
50+
fooDto.BarDtos.First().SetProperty("bar", "new-bar-value");
51+
52+
json = _jsonSerializer.Serialize(fooDto);
53+
54+
fooDto = _jsonSerializer.Deserialize<FooDto>(json);
55+
fooDto.ShouldNotBeNull();
56+
fooDto.Name.ShouldBe("new-foo-dto");
57+
fooDto.GetProperty("foo").ShouldBe("new-foo-value");
58+
59+
fooDto.BarDtos.Count.ShouldBe(1);
60+
fooDto.BarDtos.First().Name.ShouldBe("new-bar-dto");
61+
fooDto.BarDtos.First().GetProperty("bar").ShouldBe("new-bar-value");
62+
}
63+
}
64+
65+
public class FooDto : ExtensibleObject
66+
{
67+
public string Name { get; set; }
68+
69+
public List<BarDto> BarDtos { get; set; }
70+
}
71+
72+
public class BarDto : ExtensibleObject
73+
{
74+
public string Name { get; set; }
75+
}
76+
}

0 commit comments

Comments
 (0)