Skip to content

Commit b55e241

Browse files
Add a Converter to serialize empty strings as null values
Allows these values to be excluded when `IgnoreNullValues` is True
1 parent d38d4bb commit b55e241

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Text.Json;
3+
using System.Text.Json.Serialization;
4+
5+
namespace Macross.Json.Extensions.System.Text.Json.Serialization
6+
{
7+
/// <summary>
8+
/// <see cref="JsonConverter"/> to output empty strings as null values.
9+
/// </summary>
10+
public class JsonEmptyStringToNullConverter : JsonConverter<string>
11+
{
12+
/// <inheritdoc
13+
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
14+
// Don't perform a typeToConvert == null check for performance. Trust our callers will be nice.
15+
#pragma warning disable CA1062 // Validate arguments of public methods
16+
reader.GetString();
17+
#pragma warning restore CA1062 // Validate arguments of public methods
18+
19+
/// <inheritdoc/>
20+
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
21+
{
22+
// Don't perform a typeToConvert == null check for performance. Trust our callers will be nice.
23+
#pragma warning disable CA1062 // Validate arguments of public methods
24+
if (string.IsNullOrEmpty(value))
25+
writer.WriteNullValue();
26+
else
27+
writer.WriteStringValue(value);
28+
#pragma warning restore CA1062 // Validate arguments of public methods
29+
}
30+
}
31+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System.Text.Json;
2+
3+
using Macross.Json.Extensions.System.Text.Json.Serialization;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
6+
namespace Macross.Json.Extensions.Tests
7+
{
8+
[TestClass]
9+
public class JsonEmptyStringToNullConverterTests
10+
{
11+
private const string? NullString = null;
12+
13+
[TestMethod]
14+
public void TestNullIsOutputForEmptyString()
15+
{
16+
JsonSerializerOptions options = new JsonSerializerOptions();
17+
options.Converters.Add(new JsonEmptyStringToNullConverter());
18+
19+
string Json = JsonSerializer.Serialize("Test", options);
20+
Assert.AreEqual(@"""Test""", Json);
21+
22+
Json = JsonSerializer.Serialize(string.Empty, options);
23+
Assert.AreEqual("null", Json);
24+
25+
Json = JsonSerializer.Serialize(NullString, options);
26+
Assert.AreEqual("null", Json);
27+
28+
Json = JsonSerializer.Serialize(new TestClass(), options);
29+
Assert.AreEqual("{\"Str1\":null,\"Str2\":null}", Json);
30+
31+
Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One" }, options);
32+
Assert.AreEqual("{\"Str1\":\"One\",\"Str2\":null}", Json);
33+
34+
Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One", Str2 = "Two" }, options);
35+
Assert.AreEqual("{\"Str1\":\"One\",\"Str2\":\"Two\"}", Json);
36+
37+
Json = JsonSerializer.Serialize(new TestClass() { Str2 = "Two" }, options);
38+
Assert.AreEqual("{\"Str1\":null,\"Str2\":\"Two\"}", Json);
39+
40+
options = new JsonSerializerOptions();
41+
options.Converters.Add(new JsonEmptyStringToNullConverter());
42+
options.IgnoreNullValues = true;
43+
44+
Json = JsonSerializer.Serialize("Test", options);
45+
Assert.AreEqual(@"""Test""", Json);
46+
47+
Json = JsonSerializer.Serialize(string.Empty, options);
48+
Assert.AreEqual("null", Json);
49+
50+
Json = JsonSerializer.Serialize(NullString, options);
51+
Assert.AreEqual("null", Json);
52+
53+
Json = JsonSerializer.Serialize(new TestClass(), options);
54+
Assert.AreEqual("{}", Json);
55+
56+
Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One" }, options);
57+
Assert.AreEqual("{\"Str1\":\"One\"}", Json);
58+
59+
Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One", Str2 = "Two" }, options);
60+
Assert.AreEqual("{\"Str1\":\"One\",\"Str2\":\"Two\"}", Json);
61+
62+
Json = JsonSerializer.Serialize(new TestClass() { Str2 = "Two" }, options);
63+
Assert.AreEqual("{\"Str2\":\"Two\"}", Json);
64+
}
65+
66+
private class TestClass
67+
{
68+
public string? Str1 { get; set; }
69+
70+
public string? Str2 { get; set; }
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)