Skip to content

Commit 740c0ce

Browse files
author
Chris Santero
committed
Properly serialize null values
Before, returning null from an action would throw an exception. Now, it serializes null or an empty array, depending on the cardinality of the action result type.
1 parent 775330c commit 740c0ce

5 files changed

Lines changed: 101 additions & 13 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"data": [ ]
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"data": null
3+
}

JSONAPI.Tests/JSONAPI.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@
106106
</ItemGroup>
107107
<ItemGroup>
108108
<None Include="app.config" />
109+
<None Include="Data\EmptyArrayResult.json">
110+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
111+
</None>
112+
<None Include="Data\NullResourceResult.json">
113+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
114+
</None>
109115
<None Include="Data\MetadataManagerPropertyWasPresentRequest.json">
110116
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
111117
</None>

JSONAPI.Tests/Json/JsonApiMediaFormatterTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,66 @@ public void Reformats_raw_json_string_with_unquoted_keys()
307307
output.Should().Be(minifiedExpectedJson);
308308
}
309309

310+
[TestMethod]
311+
[DeploymentItem(@"Data\NullResourceResult.json")]
312+
public void Serializes_null_resource_properly()
313+
{
314+
// Arrange
315+
var modelManager = new ModelManager(new PluralizationService());
316+
modelManager.RegisterResourceType(typeof(Comment));
317+
var formatter = new JsonApiFormatter(modelManager);
318+
MemoryStream stream = new MemoryStream();
319+
320+
// Act
321+
formatter.WriteToStreamAsync(typeof(Comment), null, stream, null, null);
322+
323+
// Assert
324+
var minifiedExpectedJson = JsonHelpers.MinifyJson(File.ReadAllText("NullResourceResult.json"));
325+
string output = System.Text.Encoding.ASCII.GetString(stream.ToArray());
326+
Trace.WriteLine(output);
327+
output.Should().Be(minifiedExpectedJson);
328+
}
329+
330+
[TestMethod]
331+
[DeploymentItem(@"Data\EmptyArrayResult.json")]
332+
public void Serializes_null_resource_array_as_empty_array()
333+
{
334+
// Arrange
335+
var modelManager = new ModelManager(new PluralizationService());
336+
modelManager.RegisterResourceType(typeof(Comment));
337+
var formatter = new JsonApiFormatter(modelManager);
338+
MemoryStream stream = new MemoryStream();
339+
340+
// Act
341+
formatter.WriteToStreamAsync(typeof(Comment[]), null, stream, null, null);
342+
343+
// Assert
344+
var minifiedExpectedJson = JsonHelpers.MinifyJson(File.ReadAllText("EmptyArrayResult.json"));
345+
string output = System.Text.Encoding.ASCII.GetString(stream.ToArray());
346+
Trace.WriteLine(output);
347+
output.Should().Be(minifiedExpectedJson);
348+
}
349+
350+
[TestMethod]
351+
[DeploymentItem(@"Data\EmptyArrayResult.json")]
352+
public void Serializes_null_list_as_empty_array()
353+
{
354+
// Arrange
355+
var modelManager = new ModelManager(new PluralizationService());
356+
modelManager.RegisterResourceType(typeof(Comment));
357+
var formatter = new JsonApiFormatter(modelManager);
358+
MemoryStream stream = new MemoryStream();
359+
360+
// Act
361+
formatter.WriteToStreamAsync(typeof(List<Comment>), null, stream, null, null);
362+
363+
// Assert
364+
var minifiedExpectedJson = JsonHelpers.MinifyJson(File.ReadAllText("EmptyArrayResult.json"));
365+
string output = System.Text.Encoding.ASCII.GetString(stream.ToArray());
366+
Trace.WriteLine(output);
367+
output.Should().Be(minifiedExpectedJson);
368+
}
369+
310370
[TestMethod]
311371
[DeploymentItem(@"Data\MalformedRawJsonString.json")]
312372
public void Does_not_serialize_malformed_raw_json_string()

JSONAPI/Json/JsonApiFormatter.cs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,23 +117,39 @@ public override Task WriteToStreamAsync(System.Type type, object value, Stream w
117117
}
118118
else
119119
{
120-
Type valtype = GetSingleType(value.GetType());
121-
if (_modelManager.IsSerializedAsMany(value.GetType()))
122-
aggregator.AddPrimary(valtype, (IEnumerable<object>) value);
123-
else
124-
aggregator.AddPrimary(valtype, value);
125-
126-
//writer.Formatting = Formatting.Indented;
127-
128120
writer.WriteStartObject();
129121
writer.WritePropertyName(PrimaryDataKeyName);
130-
if (_modelManager.IsSerializedAsMany(value.GetType()))
131-
this.SerializeMany(value, writeStream, writer, serializer, aggregator);
122+
123+
if (value == null)
124+
{
125+
if (_modelManager.IsSerializedAsMany(type))
126+
{
127+
writer.WriteStartArray();
128+
writer.WriteEndArray();
129+
}
130+
else
131+
{
132+
writer.WriteNull();
133+
}
134+
}
132135
else
133-
this.Serialize(value, writeStream, writer, serializer, aggregator);
136+
{
137+
Type valtype = GetSingleType(value.GetType());
138+
if (_modelManager.IsSerializedAsMany(value.GetType()))
139+
aggregator.AddPrimary(valtype, (IEnumerable<object>) value);
140+
else
141+
aggregator.AddPrimary(valtype, value);
142+
143+
//writer.Formatting = Formatting.Indented;
134144

135-
// Include links from aggregator
136-
SerializeLinkedResources(writeStream, writer, serializer, aggregator);
145+
if (_modelManager.IsSerializedAsMany(value.GetType()))
146+
this.SerializeMany(value, writeStream, writer, serializer, aggregator);
147+
else
148+
this.Serialize(value, writeStream, writer, serializer, aggregator);
149+
150+
// Include links from aggregator
151+
SerializeLinkedResources(writeStream, writer, serializer, aggregator);
152+
}
137153

138154
writer.WriteEndObject();
139155
}

0 commit comments

Comments
 (0)