using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
[JsonConverter(typeof(NullJsonConverter))]
public HasValue<int?> Number { get; set; }
public struct HasValue<T> : IHasValue
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
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());
public static void Test()
var settings = new JsonSerializerSettings()
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
var json = JsonConvert.SerializeObject(
new Entity { Number = new HasValue<int?>(number) },
var number2 = JsonConvert.DeserializeObject<Entity>(json, settings).Number.Value;
Assert.AreEqual(number, number2, "number, number2");
Assert.AreEqual("{}", json);
Nullable<HasValue<Nullable<int>>> value = default(HasValue<int?>?);
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");