Skip to content

Commit 8cf46af

Browse files
authored
Merge pull request #1799 from riganti/system.text.json
Use System.Text.Json as a backend for view model serialization
2 parents 06964d7 + 20019bf commit 8cf46af

File tree

252 files changed

+5866
-3007
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

252 files changed

+5866
-3007
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ jobs:
118118
# target-framework: net7.0
119119
- name: Tests (net472)
120120
uses: ./.github/unittest
121-
if: matrix.os == 'windows-2022'
121+
if: ${{ (matrix.os == 'windows-2022') && (success() || failure()) }}
122122
with:
123123
project: src/Tests
124124
name: framework-tests
@@ -127,6 +127,7 @@ jobs:
127127
target-framework: net472
128128
- name: Analyzers.Tests (net6.0)
129129
uses: ./.github/unittest
130+
if: ${{ success() || failure() }}
130131
with:
131132
project: src/Analyzers/Analyzers.Tests
132133
name: analyzers-tests

src/.config/dotnet-tools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515
]
1616
}
1717
}
18-
}
18+
}

src/Api/Swashbuckle.AspNetCore.Tests/SwaggerFileGenerationTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
using Microsoft.OpenApi.Any;
1818
using Microsoft.OpenApi.Models;
1919
using Microsoft.VisualStudio.TestTools.UnitTesting;
20-
using Newtonsoft.Json;
2120
using Swashbuckle.AspNetCore.Swagger;
2221
using Swashbuckle.AspNetCore.SwaggerGen;
2322

src/Api/Swashbuckle.AspNetCore/Filters/AddTypeToModelSchemaFilter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using Microsoft.OpenApi.Interfaces;
99
using Microsoft.OpenApi.Models;
1010
using Microsoft.OpenApi.Writers;
11-
using Newtonsoft.Json;
1211
using Swashbuckle.AspNetCore.Swagger;
1312
using Swashbuckle.AspNetCore.SwaggerGen;
1413

src/AutoUI/Core/Metadata/ResourceViewModelValidationMetadataProvider.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace DotVVM.AutoUI.Metadata
1616
public class ResourceViewModelValidationMetadataProvider : IViewModelValidationMetadataProvider
1717
{
1818
private readonly IViewModelValidationMetadataProvider baseValidationMetadataProvider;
19-
private readonly ConcurrentDictionary<PropertyInfo, List<ValidationAttribute>> cache = new();
19+
private readonly ConcurrentDictionary<MemberInfo, ValidationAttribute[]> cache = new();
2020
private readonly ResourceManager errorMessages;
2121
private static readonly FieldInfo internalErrorMessageField;
2222

@@ -43,15 +43,15 @@ static ResourceViewModelValidationMetadataProvider()
4343
/// <summary>
4444
/// Gets validation attributes for the specified property.
4545
/// </summary>
46-
public IEnumerable<ValidationAttribute> GetAttributesForProperty(PropertyInfo property)
46+
public IEnumerable<ValidationAttribute> GetAttributesForProperty(MemberInfo property)
4747
{
4848
return cache.GetOrAdd(property, GetAttributesForPropertyCore);
4949
}
5050

5151
/// <summary>
5252
/// Determines validation attributes for the specified property and loads missing error messages from the resource file.
5353
/// </summary>
54-
private List<ValidationAttribute> GetAttributesForPropertyCore(PropertyInfo property)
54+
private ValidationAttribute[] GetAttributesForPropertyCore(MemberInfo property)
5555
{
5656
// process all validation attributes
5757
var results = new List<ValidationAttribute>();
@@ -73,7 +73,7 @@ private List<ValidationAttribute> GetAttributesForPropertyCore(PropertyInfo prop
7373
}
7474
}
7575

76-
return results;
76+
return results.Count == 0 ? Array.Empty<ValidationAttribute>() : results.ToArray();
7777
}
7878

7979
private bool HasDefaultErrorMessage(ValidationAttribute attribute)

src/DynamicData/DynamicData/Metadata/ResourceViewModelValidationMetadataProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.ComponentModel.DataAnnotations;
55
using System.Globalization;
6+
using System.Linq;
67
using System.Reflection;
78
using System.Resources;
89
using System.Threading;
@@ -40,8 +41,12 @@ public ResourceViewModelValidationMetadataProvider(Type errorMessagesResourceFil
4041
/// <summary>
4142
/// Gets validation attributes for the specified property.
4243
/// </summary>
43-
public IEnumerable<ValidationAttribute> GetAttributesForProperty(PropertyInfo property)
44+
public IEnumerable<ValidationAttribute> GetAttributesForProperty(MemberInfo member)
4445
{
46+
if (member is not PropertyInfo property)
47+
{
48+
return [];
49+
}
4550
return cache.GetOrAdd(new PropertyInfoCulturePair(CultureInfo.CurrentUICulture, property), GetAttributesForPropertyCore);
4651
}
4752

src/Framework/Core/DotVVM.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<EmbeddedResource Include="compiler\resources\**\*" />
1717
</ItemGroup>
1818
<ItemGroup>
19-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
19+
<PackageReference Include="System.Text.Json" Version="8.0.5" />
2020
</ItemGroup>
2121
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
2222
<PackageReference Include="System.ComponentModel.Annotations" Version="4.3.0" />

src/Framework/Core/ViewModel/BindAttribute.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace DotVVM.Framework.ViewModel
77
/// <summary>
88
/// Specifies the binding direction.
99
/// </summary>
10-
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
10+
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
1111
public class BindAttribute : Attribute
1212
{
1313

@@ -21,6 +21,17 @@ public class BindAttribute : Attribute
2121
/// </summary>
2222
public string? Name { get; set; }
2323

24+
public bool? _allowDynamicDispatch;
25+
/// <summary>
26+
/// When true, DotVVM serializer will select the JSON converter based on the runtime type, instead of deciding it ahead of time.
27+
/// This essentially enables serialization of properties defined derived types, but does not enable derive type deserialization, unless an instance of the correct type is prepopulated into the property.
28+
/// By default, dynamic dispatch is enabled for abstract types (including interfaces and System.Object).
29+
/// </summary>
30+
public bool AllowDynamicDispatch { get => _allowDynamicDispatch ?? false; set => _allowDynamicDispatch = value; }
31+
32+
/// <summary> See <see cref="AllowDynamicDispatch" /> </summary>
33+
public bool AllowsDynamicDispatch(bool defaultValue) => _allowDynamicDispatch ?? defaultValue;
34+
2435

2536
/// <summary>
2637
/// Initializes a new instance of the <see cref="BindAttribute"/> class.

src/Framework/Core/ViewModel/DefaultPropertySerialization.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
using System.Reflection;
2-
using Newtonsoft.Json;
1+
using System;
2+
using System.Reflection;
3+
using System.Text.Json.Serialization;
34

45
namespace DotVVM.Framework.ViewModel
56
{
67
public class DefaultPropertySerialization : IPropertySerialization
78
{
8-
public string ResolveName(PropertyInfo propertyInfo)
9+
static readonly Type? JsonPropertyNJ = Type.GetType("Newtonsoft.Json.JsonPropertyAttribute, Newtonsoft.Json");
10+
static readonly PropertyInfo? JsonPropertyNJPropertyName = JsonPropertyNJ?.GetProperty("PropertyName");
11+
public string ResolveName(MemberInfo propertyInfo)
912
{
1013
var bindAttribute = propertyInfo.GetCustomAttribute<BindAttribute>();
1114
if (bindAttribute != null)
@@ -16,13 +19,23 @@ public string ResolveName(PropertyInfo propertyInfo)
1619
}
1720
}
1821

19-
if (string.IsNullOrEmpty(bindAttribute?.Name))
22+
// use JsonPropertyName name if Bind attribute is not present or doesn't specify it
23+
var jsonPropertyAttribute = propertyInfo.GetCustomAttribute<JsonPropertyNameAttribute>();
24+
if (!string.IsNullOrEmpty(jsonPropertyAttribute?.Name))
2025
{
21-
// use JsonProperty name if Bind attribute is not present or doesn't specify it
22-
var jsonPropertyAttribute = propertyInfo.GetCustomAttribute<JsonPropertyAttribute>();
23-
if (!string.IsNullOrEmpty(jsonPropertyAttribute?.PropertyName))
26+
return jsonPropertyAttribute!.Name!;
27+
}
28+
29+
if (JsonPropertyNJ is not null)
30+
{
31+
var jsonPropertyNJAttribute = propertyInfo.GetCustomAttribute(JsonPropertyNJ);
32+
if (jsonPropertyNJAttribute is not null)
2433
{
25-
return jsonPropertyAttribute!.PropertyName!;
34+
var name = (string?)JsonPropertyNJPropertyName!.GetValue(jsonPropertyNJAttribute);
35+
if (!string.IsNullOrEmpty(name))
36+
{
37+
return name;
38+
}
2639
}
2740
}
2841

src/Framework/Core/ViewModel/IPropertySerialization.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ namespace DotVVM.Framework.ViewModel
44
{
55
public interface IPropertySerialization
66
{
7-
string ResolveName(PropertyInfo propertyInfo);
7+
string ResolveName(MemberInfo propertyInfo);
88
}
99
}

0 commit comments

Comments
 (0)