diff --git a/ClassLibraries/Macross.Json.Extensions/Code/System.Text.Json.Serialization/JsonEmptyStringToNullConverter.cs b/ClassLibraries/Macross.Json.Extensions/Code/System.Text.Json.Serialization/JsonEmptyStringToNullConverter.cs
new file mode 100644
index 0000000..beeb54d
--- /dev/null
+++ b/ClassLibraries/Macross.Json.Extensions/Code/System.Text.Json.Serialization/JsonEmptyStringToNullConverter.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Macross.Json.Extensions.System.Text.Json.Serialization
+{
+ ///
+ /// to output empty strings as null values.
+ ///
+ public class JsonEmptyStringToNullConverter : JsonConverter
+ {
+ ///
+ public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString();
+
+ ///
+ public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
+ {
+#pragma warning disable CA1062 // Don't perform checks for performance. Trust our callers will be nice.
+ if (string.IsNullOrEmpty(value))
+ writer.WriteNullValue();
+ else
+ writer.WriteStringValue(value);
+#pragma warning restore CA1062 // Validate arguments of public methods
+ }
+ }
+}
diff --git a/ClassLibraries/Macross.Json.Extensions/Test/JsonEmptyStringToNullConverterTests.cs b/ClassLibraries/Macross.Json.Extensions/Test/JsonEmptyStringToNullConverterTests.cs
new file mode 100644
index 0000000..27e5728
--- /dev/null
+++ b/ClassLibraries/Macross.Json.Extensions/Test/JsonEmptyStringToNullConverterTests.cs
@@ -0,0 +1,73 @@
+using System.Text.Json;
+
+using Macross.Json.Extensions.System.Text.Json.Serialization;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Macross.Json.Extensions.Tests
+{
+ [TestClass]
+ public class JsonEmptyStringToNullConverterTests
+ {
+ private const string? NullString = null;
+
+ [TestMethod]
+ public void TestNullIsOutputForEmptyString()
+ {
+ JsonSerializerOptions options = new JsonSerializerOptions();
+ options.Converters.Add(new JsonEmptyStringToNullConverter());
+
+ string Json = JsonSerializer.Serialize("Test", options);
+ Assert.AreEqual(@"""Test""", Json);
+
+ Json = JsonSerializer.Serialize(string.Empty, options);
+ Assert.AreEqual("null", Json);
+
+ Json = JsonSerializer.Serialize(NullString, options);
+ Assert.AreEqual("null", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass(), options);
+ Assert.AreEqual("{\"Str1\":null,\"Str2\":null}", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One" }, options);
+ Assert.AreEqual("{\"Str1\":\"One\",\"Str2\":null}", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One", Str2 = "Two" }, options);
+ Assert.AreEqual("{\"Str1\":\"One\",\"Str2\":\"Two\"}", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass() { Str2 = "Two" }, options);
+ Assert.AreEqual("{\"Str1\":null,\"Str2\":\"Two\"}", Json);
+
+ options = new JsonSerializerOptions();
+ options.Converters.Add(new JsonEmptyStringToNullConverter());
+ options.IgnoreNullValues = true;
+
+ Json = JsonSerializer.Serialize("Test", options);
+ Assert.AreEqual(@"""Test""", Json);
+
+ Json = JsonSerializer.Serialize(string.Empty, options);
+ Assert.AreEqual("null", Json);
+
+ Json = JsonSerializer.Serialize(NullString, options);
+ Assert.AreEqual("null", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass(), options);
+ Assert.AreEqual("{}", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One" }, options);
+ Assert.AreEqual("{\"Str1\":\"One\"}", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass() { Str1 = "One", Str2 = "Two" }, options);
+ Assert.AreEqual("{\"Str1\":\"One\",\"Str2\":\"Two\"}", Json);
+
+ Json = JsonSerializer.Serialize(new TestClass() { Str2 = "Two" }, options);
+ Assert.AreEqual("{\"Str2\":\"Two\"}", Json);
+ }
+
+ private class TestClass
+ {
+ public string? Str1 { get; set; }
+
+ public string? Str2 { get; set; }
+ }
+ }
+}