[Fork] https://stackoverflow.com/questions/56261012/how-to-serialize-using-json-net-and-ignore-a-nullable-struct-value

CSharp · Console

/Program.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters;
using System.IO;
using System.Data;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Reflection;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;	

using NUnit.Framework; // Throws NUnit.Framework.AssertionException

//https://stackoverflow.com/questions/56261012/how-to-serialize-using-json-net-and-ignore-a-nullable-struct-value

	public class Entity
	{
		[JsonConverter(typeof(NullJsonConverter))]
		public HasValue<int?> Number { get; set; }
	}

	public struct HasValue<T> : IHasValue
	{
		// Had to convert to c# 4.0 syntax for dotnetfiddle
		T m_value;
		public HasValue(T value) { this.m_value = value; }
		public T Value { get { return m_value; } set { m_value = value; } }
		
		public object GetValue() { return Value; }
	}

	internal interface IHasValue
	{
		object GetValue();
	}

	public class NullJsonConverter : JsonConverter
	{
		public override bool CanConvert(Type objectType) { throw new NotImplementedException(); }

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var valueType = objectType.GetGenericArguments()[0];
			var valueValue = serializer.Deserialize(reader, valueType);
			return Activator.CreateInstance(objectType, valueValue);
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			serializer.Serialize(writer, ((IHasValue)value).GetValue());
		}
	}

    class TestClass
    {
        public static void Test()
        {
			int? number = null;
			
			var settings = new JsonSerializerSettings()
				{ 
					DefaultValueHandling = DefaultValueHandling.Ignore,
					NullValueHandling = NullValueHandling.Ignore
				};
			var json = JsonConvert.SerializeObject(
				new Entity { Number = new HasValue<int?>(number) },
				settings);

			var number2 = JsonConvert.DeserializeObject<Entity>(json, settings).Number.Value;

			Console.WriteLine(json);
			Assert.AreEqual(number, number2, "number, number2");
			Assert.AreEqual("{}", json); // Fails because json = {"Number":null}
		}	
		
		Nullable<HasValue<Nullable<int>>> value = default(HasValue<int?>?);
	}

	public class Program
	{
		public static void Main()
		{
			Console.WriteLine("Environment version: " + Environment.Version);
			Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
			Console.WriteLine();

			try
			{
				TestClass.Test();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed with unhandled exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
	}
;