@@ -19,18 +19,21 @@ namespace JsonApiDotNetCore.Serialization
19
19
public abstract class BaseDeserializer
20
20
{
21
21
private protected static readonly CollectionConverter CollectionConverter = new ( ) ;
22
+ private readonly IJsonApiOptions _options ;
22
23
23
24
protected IResourceGraph ResourceGraph { get ; }
24
25
protected IResourceFactory ResourceFactory { get ; }
25
26
protected int ? AtomicOperationIndex { get ; set ; }
26
27
27
- protected BaseDeserializer ( IResourceGraph resourceGraph , IResourceFactory resourceFactory )
28
+ protected BaseDeserializer ( IResourceGraph resourceGraph , IResourceFactory resourceFactory , IJsonApiOptions options )
28
29
{
29
30
ArgumentGuard . NotNull ( resourceGraph , nameof ( resourceGraph ) ) ;
30
31
ArgumentGuard . NotNull ( resourceFactory , nameof ( resourceFactory ) ) ;
32
+ ArgumentGuard . NotNull ( options , nameof ( options ) ) ;
31
33
32
34
ResourceGraph = resourceGraph ;
33
35
ResourceFactory = resourceFactory ;
36
+ _options = options ;
34
37
}
35
38
36
39
/// <summary>
@@ -123,6 +126,8 @@ private IIdentifiable SetAttributes(IIdentifiable resource, IDictionary<string,
123
126
{
124
127
if ( attributeValues . TryGetValue ( attr . PublicName , out object newValue ) )
125
128
{
129
+ attributeValues . Remove ( attr . PublicName ) ;
130
+
126
131
if ( attr . Property . SetMethod == null )
127
132
{
128
133
throw new JsonApiSerializationException ( "Attribute is read-only." , $ "Attribute '{ attr . PublicName } ' is read-only.",
@@ -148,6 +153,14 @@ private IIdentifiable SetAttributes(IIdentifiable resource, IDictionary<string,
148
153
}
149
154
}
150
155
156
+ if ( ! _options . AllowUnknownFieldsInRequestBody && attributeValues . Any ( ) )
157
+ {
158
+ string attributeName = attributeValues . First ( ) . Key ;
159
+
160
+ throw new JsonApiSerializationException ( "Request body includes unknown attribute." , $ "Attribute '{ attributeName } ' does not exist.",
161
+ atomicOperationIndex : AtomicOperationIndex ) ;
162
+ }
163
+
151
164
return resource ;
152
165
}
153
166
@@ -160,24 +173,26 @@ private IIdentifiable SetAttributes(IIdentifiable resource, IDictionary<string,
160
173
/// <param name="relationshipValues">
161
174
/// Relationships and their values, as in the serialized content.
162
175
/// </param>
163
- /// <param name="relationshipAttributes ">
176
+ /// <param name="relationships ">
164
177
/// Exposed relationships for <paramref name="resource" />.
165
178
/// </param>
166
179
private IIdentifiable SetRelationships ( IIdentifiable resource , IDictionary < string , RelationshipObject > relationshipValues ,
167
- IReadOnlyCollection < RelationshipAttribute > relationshipAttributes )
180
+ IReadOnlyCollection < RelationshipAttribute > relationships )
168
181
{
169
182
ArgumentGuard . NotNull ( resource , nameof ( resource ) ) ;
170
- ArgumentGuard . NotNull ( relationshipAttributes , nameof ( relationshipAttributes ) ) ;
183
+ ArgumentGuard . NotNull ( relationships , nameof ( relationships ) ) ;
171
184
172
185
if ( relationshipValues . IsNullOrEmpty ( ) )
173
186
{
174
187
return resource ;
175
188
}
176
189
177
- foreach ( RelationshipAttribute attr in relationshipAttributes )
190
+ foreach ( RelationshipAttribute attr in relationships )
178
191
{
179
192
bool relationshipIsProvided = relationshipValues . TryGetValue ( attr . PublicName , out RelationshipObject relationshipData ) ;
180
193
194
+ relationshipValues . Remove ( attr . PublicName ) ;
195
+
181
196
if ( ! relationshipIsProvided || ! relationshipData . Data . IsAssigned )
182
197
{
183
198
continue ;
@@ -193,6 +208,14 @@ private IIdentifiable SetRelationships(IIdentifiable resource, IDictionary<strin
193
208
}
194
209
}
195
210
211
+ if ( ! _options . AllowUnknownFieldsInRequestBody && relationshipValues . Any ( ) )
212
+ {
213
+ string relationshipName = relationshipValues . First ( ) . Key ;
214
+
215
+ throw new JsonApiSerializationException ( "Request body includes unknown relationship." , $ "Relationship '{ relationshipName } ' does not exist.",
216
+ atomicOperationIndex : AtomicOperationIndex ) ;
217
+ }
218
+
196
219
return resource ;
197
220
}
198
221
0 commit comments