44using System . Text . Encodings . Web ;
55using System . Text . Json ;
66using System . Text . Json . Serialization ;
7+ using JsonApiDotNetCore . Configuration ;
8+ using JsonApiDotNetCore . Resources ;
9+ using JsonApiDotNetCore . Resources . Annotations ;
710using Microsoft . Extensions . Logging ;
811
912namespace JsonApiDotNetCore . Middleware ;
@@ -14,8 +17,69 @@ internal abstract class TraceLogWriter
1417 {
1518 WriteIndented = true ,
1619 Encoder = JavaScriptEncoder . UnsafeRelaxedJsonEscaping ,
17- ReferenceHandler = ReferenceHandler . Preserve
20+ ReferenceHandler = ReferenceHandler . IgnoreCycles ,
21+ DefaultIgnoreCondition = JsonIgnoreCondition . WhenWritingNull ,
22+ Converters =
23+ {
24+ new JsonStringEnumConverter ( ) ,
25+ new ResourceTypeInTraceJsonConverter ( ) ,
26+ new ResourceFieldInTraceJsonConverterFactory ( ) ,
27+ new IdentifiableInTraceJsonConverter ( )
28+ }
1829 } ;
30+
31+ private sealed class ResourceTypeInTraceJsonConverter : JsonConverter < ResourceType >
32+ {
33+ public override ResourceType Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
34+ {
35+ throw new NotSupportedException ( ) ;
36+ }
37+
38+ public override void Write ( Utf8JsonWriter writer , ResourceType value , JsonSerializerOptions options )
39+ {
40+ writer . WriteStringValue ( value . PublicName ) ;
41+ }
42+ }
43+
44+ private sealed class ResourceFieldInTraceJsonConverterFactory : JsonConverterFactory
45+ {
46+ public override bool CanConvert ( Type typeToConvert )
47+ {
48+ return typeToConvert . IsAssignableTo ( typeof ( ResourceFieldAttribute ) ) ;
49+ }
50+
51+ public override JsonConverter CreateConverter ( Type typeToConvert , JsonSerializerOptions options )
52+ {
53+ return new ResourceFieldInTraceJsonConverter ( ) ;
54+ }
55+
56+ private sealed class ResourceFieldInTraceJsonConverter : JsonConverter < ResourceFieldAttribute >
57+ {
58+ public override ResourceFieldAttribute Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
59+ {
60+ throw new NotSupportedException ( ) ;
61+ }
62+
63+ public override void Write ( Utf8JsonWriter writer , ResourceFieldAttribute value , JsonSerializerOptions options )
64+ {
65+ writer . WriteStringValue ( value . PublicName ) ;
66+ }
67+ }
68+ }
69+
70+ private sealed class IdentifiableInTraceJsonConverter : JsonConverter < IIdentifiable >
71+ {
72+ public override IIdentifiable Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
73+ {
74+ throw new NotSupportedException ( ) ;
75+ }
76+
77+ public override void Write ( Utf8JsonWriter writer , IIdentifiable value , JsonSerializerOptions options )
78+ {
79+ Type runtimeType = value . GetType ( ) ;
80+ JsonSerializer . Serialize ( writer , value , runtimeType , options ) ;
81+ }
82+ }
1983}
2084
2185internal sealed class TraceLogWriter < T > : TraceLogWriter
@@ -88,26 +152,12 @@ private static void WriteProperty(StringBuilder builder, PropertyInfo property,
88152 builder . Append ( ": " ) ;
89153
90154 object ? value = property . GetValue ( instance ) ;
91-
92- if ( value == null )
93- {
94- builder . Append ( "null" ) ;
95- }
96- else if ( value is string stringValue )
97- {
98- builder . Append ( '"' ) ;
99- builder . Append ( stringValue ) ;
100- builder . Append ( '"' ) ;
101- }
102- else
103- {
104- WriteObject ( builder , value ) ;
105- }
155+ WriteObject ( builder , value ) ;
106156 }
107157
108- private static void WriteObject ( StringBuilder builder , object value )
158+ private static void WriteObject ( StringBuilder builder , object ? value )
109159 {
110- if ( HasToStringOverload ( value . GetType ( ) ) )
160+ if ( value != null && value is not string && HasToStringOverload ( value . GetType ( ) ) )
111161 {
112162 builder . Append ( value ) ;
113163 }
@@ -118,28 +168,19 @@ private static void WriteObject(StringBuilder builder, object value)
118168 }
119169 }
120170
121- private static bool HasToStringOverload ( Type ? type )
171+ private static bool HasToStringOverload ( Type type )
122172 {
123- if ( type != null )
124- {
125- MethodInfo ? toStringMethod = type . GetMethod ( "ToString" , Array . Empty < Type > ( ) ) ;
126-
127- if ( toStringMethod != null && toStringMethod . DeclaringType != typeof ( object ) )
128- {
129- return true ;
130- }
131- }
132-
133- return false ;
173+ MethodInfo ? toStringMethod = type . GetMethod ( "ToString" , Array . Empty < Type > ( ) ) ;
174+ return toStringMethod != null && toStringMethod . DeclaringType != typeof ( object ) ;
134175 }
135176
136- private static string SerializeObject ( object value )
177+ private static string SerializeObject ( object ? value )
137178 {
138179 try
139180 {
140181 return JsonSerializer . Serialize ( value , SerializerOptions ) ;
141182 }
142- catch ( JsonException )
183+ catch ( Exception exception ) when ( exception is JsonException or NotSupportedException )
143184 {
144185 // Never crash as a result of logging, this is best-effort only.
145186 return "object" ;
0 commit comments