Skip to content

Commit 62dc6b8

Browse files
committed
making System.Text.Json serialization really work
deserialization still won't work out of the box, unless one uses JsonSerializerOptions.IgnoreReadOnlyProperties = false + there is an issue with deserializing HashSet<T> in .NET SDK 3.1.x and even 3.2.x (Blazor releases)
1 parent 8ad3f85 commit 62dc6b8

24 files changed

+162
-276
lines changed

.editorconfig

+10-4
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,15 @@ csharp_preserve_single_line_blocks = true
133133
# C# diagnostics overrides #
134134
###############################
135135
# CA1303: Do not pass literals as localized parameters
136-
dotnet_diagnostic.CA1303.severity = suggestion
136+
dotnet_diagnostic.CA1303.severity = none
137+
# CA1724: Type names should not match namespaces
138+
dotnet_diagnostic.CA1724.severity = none
139+
# CA2007: Consider calling ConfigureAwait on the awaited task
140+
dotnet_diagnostic.CA2007.severity = suggestion
137141
# CC0022: Should dispose object
138142
# as of Apr 2020 CodeCracker doesn't support C# 8.0, so inline using statemates are not "seen" by it
139-
dotnet_diagnostic.CC0022.severity = suggestion
140-
# S1135: Track uses of "TODO" tags
141-
dotnet_diagnostic.S1135.severity = suggestion
143+
dotnet_diagnostic.CC0022.severity = none
144+
# SA1101: Prefix local calls with this
145+
dotnet_diagnostic.SA1101.severity = none
146+
# S3241: Methods should not return values that are never used
147+
dotnet_diagnostic.S3241.severity = none

CodeAnalysis.ruleset

-217
This file was deleted.

CodeCave.Threejs.Entities.sln

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 16
44
VisualStudioVersion = 16.0.30011.22
@@ -9,13 +9,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
99
ProjectSection(SolutionItems) = preProject
1010
.editorconfig = .editorconfig
1111
azure-pipelines.yml = azure-pipelines.yml
12-
CodeAnalysis.ruleset = CodeAnalysis.ruleset
1312
Directory.Build.props = Directory.Build.props
1413
Directory.Build.targets = Directory.Build.targets
1514
LICENSE = LICENSE
1615
NuGet.config = NuGet.config
1716
README.md = README.md
1817
stylecop.json = stylecop.json
18+
stylecop.ruleset = stylecop.ruleset
1919
EndProjectSection
2020
EndProject
2121
Global

Directory.Build.targets

+36-17
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,67 @@
88
</PropertyGroup>
99
-->
1010

11-
<!-- Analyzers-related configuration -->
1211
<PropertyGroup>
13-
<RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
1412
<SolutionDir Condition="'$(SolutionDir)'==''">$(MSBuildThisFileDirectory)</SolutionDir>
15-
<CodeAnalysisRuleSet>$(SolutionDir)\CodeAnalysis.ruleset</CodeAnalysisRuleSet>
1613
</PropertyGroup>
1714

18-
<!-- StyleCop Analyzer-related configuration -->
19-
<PropertyGroup Condition="Exists('$(SolutionDir)\CodeAnalysis.ruleset') And '$(BuildingInsideVisualStudio)' == 'true'">
20-
<StyleCopTreatErrorsAsWarnings>True</StyleCopTreatErrorsAsWarnings>
15+
<!-- Documentation-related settings -->
16+
<PropertyGroup>
17+
<!--
18+
Make sure any documentation comments which are included in code get checked for syntax during the build, but do
19+
not report warnings for missing comments.
20+
21+
CS1573: Parameter 'parameter' has no matching param tag in the XML comment for 'parameter' (but other parameters do)
22+
CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
23+
-->
24+
<NoWarn>$(NoWarn),1573,1591,1712</NoWarn>
2125
</PropertyGroup>
22-
<ItemGroup Condition="Exists('$(SolutionDir)\stylecop.json') And '$(BuildingInsideVisualStudio)' == 'true'">
23-
<AdditionalFiles Include="$(SolutionDir)\stylecop.json" />
26+
27+
<!-- Analyzers-related configuration -->
28+
<PropertyGroup>
29+
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
30+
<RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
31+
<StyleCopTreatErrorsAsWarnings>true</StyleCopTreatErrorsAsWarnings>
32+
<CodeAnalysisRuleSet Condition="Exists('$(SolutionDir)\stylecop.ruleset')" >$(SolutionDir)\stylecop.ruleset</CodeAnalysisRuleSet>
33+
</PropertyGroup>
34+
35+
<ItemGroup>
36+
<!-- StyleCop Analyzer-related configuration -->
37+
<AdditionalFiles Include="$(SolutionDir)\stylecop.json" Condition="Exists('$(SolutionDir)\stylecop.json')" />
2438
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.*">
2539
<PrivateAssets>all</PrivateAssets>
2640
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2741
</PackageReference>
2842
<None Remove="**\*.Cache" />
29-
</ItemGroup>
3043

31-
<!-- FxCop Analyzer-related configuration -->
32-
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
44+
<!-- FxCop Analyzer-related configuration -->
3345
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0-beta*">
3446
<PrivateAssets>all</PrivateAssets>
3547
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3648
</PackageReference>
37-
</ItemGroup>
3849

39-
<!-- CodeCracker Analyzer-related configuration -->
40-
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
50+
<!-- CodeCracker Analyzer-related configuration -->
4151
<PackageReference Include="codecracker.CSharp" Version="1.1.*">
4252
<PrivateAssets>all</PrivateAssets>
4353
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4454
</PackageReference>
45-
</ItemGroup>
4655

47-
<!-- Sonar Analyzer-related configuration -->
48-
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
56+
<!-- Sonar Analyzer-related configuration -->
4957
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.6.*">
5058
<PrivateAssets>all</PrivateAssets>
5159
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
5260
</PackageReference>
5361
</ItemGroup>
5462

63+
<!--
64+
Disable analyzers when building a project inside Visual Studio.
65+
Note that analyzer behavior for IntelliSense purposes is not altered by this.
66+
-->
67+
<Target Name="DisableAnalyzersForVisualStudioBuild" BeforeTargets="CoreCompile"
68+
Condition="'$(BuildingInsideVisualStudio)' == 'true' And '$(BuildingProject)' == 'true' And '$(Configuration)' == 'Debug'">
69+
<ItemGroup>
70+
<Analyzer Remove="@(Analyzer)"/>
71+
</ItemGroup>
72+
</Target>
73+
5574
</Project>

src/CodeCave.Threejs.Entities.csproj

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
@@ -19,6 +19,14 @@
1919
<PackageTags>nuget, package, library, three.js, revit, export</PackageTags>
2020
</PropertyGroup>
2121

22+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
23+
<CodeAnalysisRuleSet>..\stylecop.ruleset</CodeAnalysisRuleSet>
24+
</PropertyGroup>
25+
26+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard2.0|AnyCPU'">
27+
<CodeAnalysisRuleSet>..\stylecop.ruleset</CodeAnalysisRuleSet>
28+
</PropertyGroup>
29+
2230
<ItemGroup>
2331
<PackageReference Include="JsonSubTypes" Version="1.7.0" />
2432
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />

src/Extensions/Object3DExtensions.cs

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
42
using System.Linq;
53

64
namespace CodeCave.Threejs.Entities
@@ -11,7 +9,7 @@ public static class Object3DExtensions
119
/// <param name="objectScene">The object scene.</param>
1210
/// <param name="otherScene">The other scene.</param>
1311
/// <param name="newPosition">The new position of merged objects after merge.</param>
14-
/// <returns></returns>
12+
/// <returns>Returns the modified <see cref="ObjectScene"/> with other scene merged into it. </returns>
1513
/// <exception cref="ArgumentNullException">objectScene
1614
/// or
1715
/// otherScene.</exception>
@@ -55,9 +53,9 @@ public static ObjectScene Merge(this ObjectScene objectScene, ObjectScene otherS
5553
/// <param name="depth">The depth.</param>
5654
/// <param name="position">The position.</param>
5755
/// <param name="color">The color.</param>
58-
/// <returns></returns>
56+
/// <returns>Returns the original <see cref="ObjectScene"/> with cube added into it.</returns>
5957
/// <exception cref="ArgumentNullException">objectScene.</exception>
60-
public static Object3D AddCube(this ObjectScene objectScene, double width, double height, double depth, Vector3 position = default, int color = 11674146)
58+
public static ObjectScene AddCube(this ObjectScene objectScene, double width, double height, double depth, Vector3 position = default, int color = 11674146)
6159
{
6260
if (objectScene is null)
6361
throw new ArgumentNullException(nameof(objectScene));
@@ -81,10 +79,10 @@ public static Object3D AddCube(this ObjectScene objectScene, double width, doubl
8179
};
8280
objectScene.Object.AddChild(cubeObject);
8381

84-
return cubeObject;
82+
return objectScene;
8583
}
8684

87-
internal static IEnumerable<Object3D> Flatten(this IEnumerable<Object3D> collection)
85+
internal static System.Collections.Generic.IEnumerable<Object3D> Flatten(this System.Collections.Generic.IEnumerable<Object3D> collection)
8886
{
8987
foreach (var obj in collection)
9088
{

src/Geometries/Geometry.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace CodeCave.Threejs.Entities
2020
[DataContract]
2121
[Newtonsoft.Json.JsonConverter(typeof(JsonSubtypes), nameof(Type))]
2222
[JsonSubtypes.KnownSubType(typeof(BoxGeometry), nameof(BoxGeometry))]
23+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.GeometryConverter))]
2324
public partial class Geometry : IEquatable<Geometry>
2425
{
2526
/// <summary>Initializes a new instance of the <see cref="Geometry"/> class.</summary>
@@ -47,12 +48,12 @@ public Geometry(string uuid)
4748
[DataMember(Name = "uuid")]
4849
[JsonProperty("uuid")]
4950
[JsonPropertyName("uuid")]
50-
public string Uuid { get; private set; }
51+
public string Uuid { get; internal set; }
5152

5253
[DataMember(Name = "data")]
5354
[JsonProperty("data")]
5455
[JsonPropertyName("data")]
55-
public virtual GeometryData Data { get; private set; }
56+
public virtual GeometryData Data { get; internal set; }
5657

5758
/// <summary>Adds the point to the vertices.</summary>
5859
/// <param name="vertex">The vertex.</param>

src/Materials/Material.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace CodeCave.Threejs.Entities
2020
[Newtonsoft.Json.JsonConverter(typeof(JsonSubtypes), nameof(Type))]
2121
[JsonSubtypes.KnownSubType(typeof(MeshPhongMaterial), nameof(MeshPhongMaterial))]
2222
[JsonSubtypes.KnownSubType(typeof(MeshStandardMaterial), nameof(MeshStandardMaterial))]
23+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.MaterialConverter))]
2324
public class Material : IEquatable<Material>, IEqualityComparer<Material>
2425
{
2526
/// <summary>Initializes a new instance of the <see cref="Material"/> class.</summary>
@@ -38,7 +39,7 @@ protected Material(string uuid)
3839
[DataMember(Name = "uuid")]
3940
[JsonProperty("uuid")]
4041
[JsonPropertyName("uuid")]
41-
public string Uuid { get; private set; }
42+
public string Uuid { get; internal set; }
4243

4344
/// <summary>
4445
/// Gets or sets the optional name of the object (doesn't need to be unique).

src/Materials/MeshPhongMaterial.cs

+8-9
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ namespace CodeCave.Threejs.Entities
1818
/// ReSharper disable once InheritdocConsiderUsage
1919
[Serializable]
2020
[DataContract]
21-
// [JsonConverter(typeof(MaterialConverter))]
2221
public sealed class MeshPhongMaterial : Material
2322
{
2423
public MeshPhongMaterial(string uuid)
@@ -43,8 +42,8 @@ public MeshPhongMaterial(string uuid)
4342
[DataMember(Name = "color")]
4443
[JsonProperty("color")]
4544
[JsonPropertyName("color")]
46-
[Newtonsoft.Json.JsonConverter(typeof(ColorIntConverter))]
47-
[System.Text.Json.Serialization.JsonConverter(typeof(ColorIntConverterMicrosoft))]
45+
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftJson.ColorIntConverter))]
46+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.ColorIntConverter))]
4847
public Color Color { get; set; } = 16777215;
4948

5049
/// <summary>
@@ -56,8 +55,8 @@ public MeshPhongMaterial(string uuid)
5655
[DataMember(Name = "ambient")]
5756
[JsonProperty("ambient")]
5857
[JsonPropertyName("ambient")]
59-
[Newtonsoft.Json.JsonConverter(typeof(ColorIntConverter))]
60-
[System.Text.Json.Serialization.JsonConverter(typeof(ColorIntConverterMicrosoft))]
58+
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftJson.ColorIntConverter))]
59+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.ColorIntConverter))]
6160

6261
public Color Ambient { get; set; } = 16777215;
6362

@@ -71,8 +70,8 @@ public MeshPhongMaterial(string uuid)
7170
[DataMember(Name = "emissive")]
7271
[JsonProperty("emissive")]
7372
[JsonPropertyName("emissive")]
74-
[Newtonsoft.Json.JsonConverter(typeof(ColorIntConverter))]
75-
[System.Text.Json.Serialization.JsonConverter(typeof(ColorIntConverterMicrosoft))]
73+
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftJson.ColorIntConverter))]
74+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.ColorIntConverter))]
7675
public Color Emissive { get; set; } = 1;
7776

7877
/// <summary>
@@ -85,8 +84,8 @@ public MeshPhongMaterial(string uuid)
8584
[DataMember(Name = "specular")]
8685
[JsonProperty("specular")]
8786
[JsonPropertyName("specular")]
88-
[Newtonsoft.Json.JsonConverter(typeof(ColorIntConverter))]
89-
[System.Text.Json.Serialization.JsonConverter(typeof(ColorIntConverterMicrosoft))]
87+
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftJson.ColorIntConverter))]
88+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.ColorIntConverter))]
9089
public Color Specular { get; set; } = 1118481;
9190

9291
/// <summary>

src/Materials/MeshStandardMaterial.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
namespace CodeCave.Threejs.Entities
77
{
88
[Serializable]
9-
// [JsonConverter(typeof(MaterialConverter))]
109
public class MeshStandardMaterial : Material
1110
{
1211
public MeshStandardMaterial(string uuid)
@@ -31,8 +30,8 @@ public MeshStandardMaterial(string uuid)
3130
[DataMember(Name = "color")]
3231
[JsonProperty("color")]
3332
[JsonPropertyName("color")]
34-
[Newtonsoft.Json.JsonConverter(typeof(ColorIntConverter))]
35-
[System.Text.Json.Serialization.JsonConverter(typeof(ColorIntConverterMicrosoft))]
33+
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftJson.ColorIntConverter))]
34+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.ColorIntConverter))]
3635
public Color Color { get; set; } = 11674146;
3736

3837
/// <summary>

src/Math/Color.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
namespace CodeCave.Threejs.Entities
77
{
88
[Serializable]
9-
[JsonConverter(typeof(ColorIntConverter))]
10-
[System.Text.Json.Serialization.JsonConverter(typeof(ColorIntConverterMicrosoft))]
9+
[JsonConverter(typeof(NewtonsoftJson.ColorIntConverter))]
10+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.ColorIntConverter))]
1111
public class Color
1212
{
1313
private readonly int integerValue;

src/Math/Vector3.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,8 @@ public override int GetHashCode()
114114
return $@"{X},{Y},{Z}".GetHashCode();
115115
}
116116

117-
/// <summary>
118-
/// Compares to.
119-
/// </summary>
120-
/// <param name="other">a.</param>
121-
/// <returns></returns>
117+
/// <summary>Compares to.</summary>
118+
/// <param name="other">The other.</param>
122119
[SuppressMessage("Major Code Smell", "S1121:Assignments should not be made from within sub-expressions", Justification = "It's more compact like this.")]
123120
public int CompareTo(Vector3 other)
124121
{

src/ObjectScene.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public IReadOnlyCollection<Material> Materials
9090
[DataMember(Name = "metadata")]
9191
[JsonProperty("metadata")]
9292
[JsonPropertyName("metadata")]
93-
private ObjectMetadata Metadata { get; }
93+
private ObjectMetadata Metadata { get; set; }
9494

9595
/// <summary>Adds the geometry.</summary>
9696
/// <param name="geometry">The geometry.</param>

src/Objects/Object3D.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace CodeCave.Threejs.Entities
1818
[Newtonsoft.Json.JsonConverter(typeof(JsonSubtypes), nameof(Type))]
1919
[JsonSubtypes.KnownSubType(typeof(Scene), nameof(Scene))]
2020
[JsonSubtypes.KnownSubType(typeof(Group), nameof(Group))]
21+
[System.Text.Json.Serialization.JsonConverter(typeof(Utf8Json.Object3DConverter))]
2122
public class Object3D : IEquatable<Object3D>, IEqualityComparer<Object3D>
2223
{
2324
private HashSet<Object3D> children;
@@ -291,7 +292,7 @@ public bool Equals(Object3D x, Object3D y)
291292
/// <summary>Returns a hash code for this instance.</summary>
292293
/// <param name="obj">The object.</param>
293294
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
294-
/// <exception cref="ArgumentNullException">obj</exception>
295+
/// <exception cref="ArgumentNullException">obj is null.</exception>
295296
public int GetHashCode(Object3D obj)
296297
{
297298
if (obj is null)

src/Serialization/ColorIntConverter.cs src/Serialization/NewtonsoftJson/ColorIntConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Diagnostics.CodeAnalysis;
33
using Newtonsoft.Json;
44

5-
namespace CodeCave.Threejs.Entities
5+
namespace CodeCave.Threejs.Entities.NewtonsoftJson
66
{
77
[SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "This class is a Json.NET converter set via prop attributes")]
88
internal class ColorIntConverter : JsonConverter<Color>

src/Serialization/JsonConverter.cs src/Serialization/Polyfill/JsonConverterAttribute.cs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public sealed class JsonConverterAttribute : Attribute
88
public JsonConverterAttribute(Type type)
99
{
1010
// does nothing on .NET Framework 4.5
11+
type?.ToString();
1112
}
1213
}
1314
}

src/Serialization/JsonPropertyNameAttribute.cs src/Serialization/Polyfill/JsonPropertyNameAttribute.cs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public sealed class JsonPropertyNameAttribute : Attribute
88
public JsonPropertyNameAttribute(string name)
99
{
1010
// does nothing on .NET Framework 4.5
11+
name?.ToString();
1112
}
1213
}
1314
}

src/Serialization/ColorIntConverterMicrosoft.cs src/Serialization/Utf8Json/ColorIntConverter.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
namespace CodeCave.Threejs.Entities
1+
namespace CodeCave.Threejs.Entities.Utf8Json
22
{
3-
public class ColorIntConverterMicrosoft
3+
public class ColorIntConverter
44
#if NET45
55
{
66
}
@@ -27,7 +27,7 @@ public override void Write(
2727
throw new System.ArgumentNullException(nameof(writer));
2828

2929
var integerValue = (int)value;
30-
writer.WriteStringValue(integerValue.ToString(System.Globalization.CultureInfo.InvariantCulture));
30+
writer.WriteNumberValue(integerValue);
3131
}
3232
}
3333
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace CodeCave.Threejs.Entities.Utf8Json
2+
{
3+
public class GeometryConverter : PolymorphicJsonConverter<Geometry>
4+
{
5+
}
6+
}

0 commit comments

Comments
 (0)