Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2a8a02f

Browse files
Merge pull request #461 from json-api-dotnet/fix/#454
Omit null attributes in included array
2 parents c633c71 + 53392fd commit 2a8a02f

File tree

3 files changed

+25
-20
lines changed

3 files changed

+25
-20
lines changed

‎src/JsonApiDotNetCore/Builders/DocumentBuilder.cs‎

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,15 @@ public ResourceObject GetData(ContextEntity contextEntity, IIdentifiable entity,
138138

139139
return data;
140140
}
141-
private bool ShouldIncludeAttribute(AttrAttribute attr, object attributeValue)
141+
private bool ShouldIncludeAttribute(AttrAttribute attr, object attributeValue,RelationshipAttributerelationship=null)
142142
{
143143
return OmitNullValuedAttribute(attr, attributeValue) == false
144144
&& attr.InternalAttributeName != nameof(Identifiable.Id)
145145
&& ((_jsonApiContext.QuerySet == null
146146
|| _jsonApiContext.QuerySet.Fields.Count == 0)
147-
|| _jsonApiContext.QuerySet.Fields.Contains(attr.InternalAttributeName));
147+
|| _jsonApiContext.QuerySet.Fields.Contains(relationship != null ?
148+
$"{relationship.InternalRelationshipName}.{attr.InternalAttributeName}" :
149+
attr.InternalAttributeName));
148150
}
149151

150152
private bool OmitNullValuedAttribute(AttrAttribute attr, object attributeValue)
@@ -225,13 +227,13 @@ private List<ResourceObject> IncludeRelationshipChain(
225227
{
226228
foreach (IIdentifiable includedEntity in hasManyNavigationEntity)
227229
{
228-
included = AddIncludedEntity(included, includedEntity);
230+
included = AddIncludedEntity(included, includedEntity,relationship);
229231
included = IncludeSingleResourceRelationships(included, includedEntity, relationship, relationshipChain, relationshipChainIndex);
230232
}
231233
}
232234
else
233235
{
234-
included = AddIncludedEntity(included, (IIdentifiable)navigationEntity);
236+
included = AddIncludedEntity(included, (IIdentifiable)navigationEntity,relationship);
235237
included = IncludeSingleResourceRelationships(included, (IIdentifiable)navigationEntity, relationship, relationshipChain, relationshipChainIndex);
236238
}
237239

@@ -254,9 +256,9 @@ private List<ResourceObject> IncludeSingleResourceRelationships(
254256
}
255257

256258

257-
private List<ResourceObject> AddIncludedEntity(List<ResourceObject> entities, IIdentifiable entity)
259+
private List<ResourceObject> AddIncludedEntity(List<ResourceObject> entities, IIdentifiable entity,RelationshipAttributerelationship)
258260
{
259-
var includedEntity = GetIncludedEntity(entity);
261+
var includedEntity = GetIncludedEntity(entity,relationship);
260262

261263
if (entities == null)
262264
entities = new List<ResourceObject>();
@@ -270,7 +272,7 @@ private List<ResourceObject> AddIncludedEntity(List<ResourceObject> entities, II
270272
return entities;
271273
}
272274

273-
private ResourceObject GetIncludedEntity(IIdentifiable entity)
275+
private ResourceObject GetIncludedEntity(IIdentifiable entity,RelationshipAttributerelationship)
274276
{
275277
if (entity == null) return null;
276278

@@ -281,13 +283,14 @@ private ResourceObject GetIncludedEntity(IIdentifiable entity)
281283

282284
data.Attributes = new Dictionary<string, object>();
283285

284-
foreach(varattrincontextEntity.Attributes)
286+
contextEntity.Attributes.ForEach(attr =>
285287
{
286-
if (attr.InternalAttributeName == nameof(Identifiable.Id))
287-
continue;
288-
289-
data.Attributes.Add(attr.PublicAttributeName, attr.GetValue(entity));
290-
}
288+
var attributeValue = attr.GetValue(entity);
289+
if (ShouldIncludeAttribute(attr, attributeValue, relationship))
290+
{
291+
data.Attributes.Add(attr.PublicAttributeName, attributeValue);
292+
}
293+
});
291294

292295
return data;
293296
}

‎test/JsonApiDotNetCoreExampleTests/Acceptance/Extensibility/NullValuedAttributeHandlingTests.cs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ public NullValuedAttributeHandlingTests(TestFixture<TestStartup> fixture)
2121
{
2222
_fixture = fixture;
2323
_dbContext = fixture.GetService<AppDbContext>();
24+
var person = new Person { FirstName = "Bob", LastName = null };
2425
_todoItem = new TodoItem
2526
{
2627
Description = null,
2728
Ordinal = 1,
2829
CreatedDate = DateTime.Now,
29-
AchievedDate = DateTime.Now.AddDays(2)
30+
AchievedDate = DateTime.Now.AddDays(2),
31+
Owner = person
3032
};
3133
_todoItem = _dbContext.TodoItems.Add(_todoItem).Entity;
3234
}
@@ -86,9 +88,9 @@ public async Task CheckNullBehaviorCombination(bool? omitNullValuedAttributes, b
8688

8789
var httpMethod = new HttpMethod("GET");
8890
var queryString = allowClientOverride.HasValue
89-
? $"?omitNullValuedAttributes={clientOverride}"
91+
? $"&omitNullValuedAttributes={clientOverride}"
9092
: "";
91-
var route = $"/api/v1/todo-items/{_todoItem.Id}{queryString}";
93+
var route = $"/api/v1/todo-items/{_todoItem.Id}?include=owner{queryString}";
9294
var request = new HttpRequestMessage(httpMethod, route);
9395

9496
// act
@@ -98,6 +100,7 @@ public async Task CheckNullBehaviorCombination(bool? omitNullValuedAttributes, b
98100

99101
// assert. does response contain a null valued attribute
100102
Assert.Equal(omitsNulls, !deserializeBody.Data.Attributes.ContainsKey("description"));
103+
Assert.Equal(omitsNulls, !deserializeBody.Included[0].Attributes.ContainsKey("last-name"));
101104

102105
}
103106
}

‎test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/SparseFieldSetTests.cs‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ public async Task Fields_Query_Selects_Fieldset_With_HasOne()
194194
Assert.Equal(owner.StringId, included.Id);
195195
Assert.Equal(owner.FirstName, included.Attributes["first-name"]);
196196
Assert.Equal((long)owner.Age, included.Attributes["age"]);
197-
Assert.Null(included.Attributes["last-name"]);
198-
197+
Assert.DoesNotContain("last-name", included.Attributes.Keys);
199198
}
200199

201200
[Fact]
@@ -233,8 +232,8 @@ public async Task Fields_Query_Selects_Fieldset_With_HasMany()
233232
var todoItem = todoItems.FirstOrDefault(i => i.StringId == includedItem.Id);
234233
Assert.NotNull(todoItem);
235234
Assert.Equal(todoItem.Description, includedItem.Attributes["description"]);
236-
Assert.Equal(default(long), includedItem.Attributes["ordinal"]);
237-
Assert.Equal(default(DateTime),(DateTime)includedItem.Attributes["created-date"]);
235+
Assert.DoesNotContain("ordinal", includedItem.Attributes.Keys);
236+
Assert.DoesNotContain("created-date",includedItem.Attributes.Keys);
238237
}
239238
}
240239
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /