﻿using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Modules.JsonNet
{
    /// <summary>
    /// IFormatter implementation based on Newtonsoft.Json serialization.
    /// Requires the Serializable attribute and optionally the  ISerializable interface.
    /// Reads/writes fields, including inherited and compiler generated.
    /// Reconstructs an identical object graph on deserialization.
    /// </summary>
    public class JsonNetFormatter : IFormatter
    {
        private readonly JsonSerializer _serializer;

        public SerializationBinder Binder{ get; set; }
        public StreamingContext Context { get; set; }
        public ISurrogateSelector SurrogateSelector { get; set; }

        public JsonNetFormatter()
        {
            var settings = new JsonSerializerSettings()
            {
                ContractResolver = new DefaultContractResolver
                {
                    IgnoreSerializableAttribute = false,
                    SerializeCompilerGeneratedMembers = true
                },
                PreserveReferencesHandling = PreserveReferencesHandling.All,
                TypeNameHandling = TypeNameHandling.All,
                TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
                
            };
            _serializer = JsonSerializer.Create(settings);
        }

        public object Deserialize(Stream serializationStream)
        {
            var reader = new JsonTextReader(new StreamReader(serializationStream));
            return _serializer.Deserialize(reader);
        }

        public void Serialize(Stream serializationStream, object graph)
        {
            var writer = new JsonTextWriter(new StreamWriter(serializationStream));
            _serializer.Serialize(writer, graph);
            writer.Flush();
        }
    }
}

﻿using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Modules.JsonNet
{
    /// <summary>
    /// IFormatter implementation based on Newtonsoft.Json serialization.
    /// Requires the Serializable attribute and optionally the  ISerializable interface.
    /// Reads/writes fields, including inherited and compiler generated.
    /// Reconstructs an identical object graph on deserialization.
    /// </summary>
    public class JsonNetFormatter : IFormatter
    {
        private readonly JsonSerializer _serializer;

        public SerializationBinder Binder{ get; set; }
        public StreamingContext Context { get; set; }
        public ISurrogateSelector SurrogateSelector { get; set; }

        public JsonNetFormatter()
        {
            var settings = new JsonSerializerSettings()
            {
                ContractResolver = new DefaultContractResolver
                {
                    IgnoreSerializableAttribute = false,
                    SerializeCompilerGeneratedMembers = true
                },
                PreserveReferencesHandling = PreserveReferencesHandling.All,
                TypeNameHandling = TypeNameHandling.All,
                TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
                MissingMemberHandling = MissingMemberHandling.Ignore
            };
            _serializer = JsonSerializer.Create(settings);
        }

        public object Deserialize(Stream serializationStream)
        {
            var reader = new JsonTextReader(new StreamReader(serializationStream));
            return _serializer.Deserialize(reader);
        }

        public void Serialize(Stream serializationStream, object graph)
        {
            var writer = new JsonTextWriter(new StreamWriter(serializationStream));
            _serializer.Serialize(writer, graph);
            writer.Flush();
        }
    }
}

Allow missing members without throwing exceptions
Allow missing members without throwing exceptions

BinaryFormatter does not always throw exceptions when a class member does not exist from the serialized data, but Newtonsoft.Json does.  This allows using JSON config files that are version-independent.  This may be better as a configurable option somehow, rather than explicitly always enabled.