@@ -44,9 +44,9 @@ public override ResourceObject Read(ref Utf8JsonReader reader, Type typeToConver
44
44
45
45
var resourceObject = new ResourceObject
46
46
{
47
- // The 'attributes' element may occur before 'type', but we need to know the resource type before we can deserialize attributes
48
- // into their corresponding CLR types.
49
- Type = PeekType ( ref reader )
47
+ // The 'attributes' or 'relationships' element may occur before 'type', but we need to know the resource type
48
+ // before we can deserialize attributes/relationships into their corresponding CLR types.
49
+ Type = PeekType ( reader )
50
50
} ;
51
51
52
52
ResourceType ? resourceType = resourceObject . Type != null ? _resourceGraph . FindResourceType ( resourceObject . Type ) : null ;
@@ -99,7 +99,15 @@ public override ResourceObject Read(ref Utf8JsonReader reader, Type typeToConver
99
99
}
100
100
case "relationships" :
101
101
{
102
- resourceObject . Relationships = ReadRelationships ( ref reader , options ) ;
102
+ if ( resourceType != null )
103
+ {
104
+ resourceObject . Relationships = ReadRelationships ( ref reader , options , resourceType ) ;
105
+ }
106
+ else
107
+ {
108
+ reader . Skip ( ) ;
109
+ }
110
+
103
111
break ;
104
112
}
105
113
case "links" :
@@ -127,27 +135,27 @@ public override ResourceObject Read(ref Utf8JsonReader reader, Type typeToConver
127
135
throw GetEndOfStreamError ( ) ;
128
136
}
129
137
130
- private static string ? PeekType ( ref Utf8JsonReader reader )
138
+ private static string ? PeekType ( Utf8JsonReader reader )
131
139
{
132
- // https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0#an-alternative-way-to-do-polymorphic-deserialization
133
- Utf8JsonReader readerClone = reader ;
140
+ // This method receives a clone of the reader (which is a struct, and there's no ref modifier on the parameter),
141
+ // so advancing here doesn't affect the reader position of the caller.
134
142
135
- while ( readerClone . Read ( ) )
143
+ while ( reader . Read ( ) )
136
144
{
137
- if ( readerClone . TokenType == JsonTokenType . PropertyName )
145
+ if ( reader . TokenType == JsonTokenType . PropertyName )
138
146
{
139
- string ? propertyName = readerClone . GetString ( ) ;
140
- readerClone . Read ( ) ;
147
+ string ? propertyName = reader . GetString ( ) ;
148
+ reader . Read ( ) ;
141
149
142
150
switch ( propertyName )
143
151
{
144
152
case "type" :
145
153
{
146
- return readerClone . GetString ( ) ;
154
+ return reader . GetString ( ) ;
147
155
}
148
156
default :
149
157
{
150
- readerClone . Skip ( ) ;
158
+ reader . Skip ( ) ;
151
159
break ;
152
160
}
153
161
}
@@ -181,7 +189,7 @@ public override ResourceObject Read(ref Utf8JsonReader reader, Type typeToConver
181
189
string extensionNamespace = attributeName [ ..extensionSeparatorIndex ] ;
182
190
string extensionName = attributeName [ ( extensionSeparatorIndex + 1 ) ..] ;
183
191
184
- ValidateExtensionInAttributes ( extensionNamespace , extensionName , reader ) ;
192
+ ValidateExtensionInAttributes ( extensionNamespace , extensionName , resourceType , reader ) ;
185
193
reader . Skip ( ) ;
186
194
continue ;
187
195
}
@@ -232,12 +240,13 @@ public override ResourceObject Read(ref Utf8JsonReader reader, Type typeToConver
232
240
}
233
241
234
242
// Currently exposed for internal use only, so we don't need a breaking change when adding support for multiple extensions.
235
- private protected virtual void ValidateExtensionInAttributes ( string extensionNamespace , string extensionName , Utf8JsonReader reader )
243
+ private protected virtual void ValidateExtensionInAttributes ( string extensionNamespace , string extensionName , ResourceType resourceType ,
244
+ Utf8JsonReader reader )
236
245
{
237
246
throw new JsonException ( $ "Unsupported usage of JSON:API extension '{ extensionNamespace } ' in attributes.") ;
238
247
}
239
248
240
- private Dictionary < string , RelationshipObject ? > ReadRelationships ( ref Utf8JsonReader reader , JsonSerializerOptions options )
249
+ private Dictionary < string , RelationshipObject ? > ReadRelationships ( ref Utf8JsonReader reader , JsonSerializerOptions options , ResourceType resourceType )
241
250
{
242
251
var relationships = new Dictionary < string , RelationshipObject ? > ( ) ;
243
252
@@ -261,7 +270,7 @@ private protected virtual void ValidateExtensionInAttributes(string extensionNam
261
270
string extensionNamespace = relationshipName [ ..extensionSeparatorIndex ] ;
262
271
string extensionName = relationshipName [ ( extensionSeparatorIndex + 1 ) ..] ;
263
272
264
- ValidateExtensionInRelationships ( extensionNamespace , extensionName , reader ) ;
273
+ ValidateExtensionInRelationships ( extensionNamespace , extensionName , resourceType , reader ) ;
265
274
reader . Skip ( ) ;
266
275
continue ;
267
276
}
@@ -277,7 +286,8 @@ private protected virtual void ValidateExtensionInAttributes(string extensionNam
277
286
}
278
287
279
288
// Currently exposed for internal use only, so we don't need a breaking change when adding support for multiple extensions.
280
- private protected virtual void ValidateExtensionInRelationships ( string extensionNamespace , string extensionName , Utf8JsonReader reader )
289
+ private protected virtual void ValidateExtensionInRelationships ( string extensionNamespace , string extensionName , ResourceType resourceType ,
290
+ Utf8JsonReader reader )
281
291
{
282
292
throw new JsonException ( $ "Unsupported usage of JSON:API extension '{ extensionNamespace } ' in relationships.") ;
283
293
}
0 commit comments