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;
public class EsiObjConverter<T> : JsonConverter
const string EsiObjName = "EsiObj";
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
var contract = serializer.ContractResolver.ResolveContract(value.GetType()) as JsonObjectContract;
throw new JsonSerializationException(string.Format("Non-object type {0}", value));
writer.WriteStartObject();
bool lastWasEsiProperty = false;
foreach (var property in contract.Properties.Where(p => p.Readable && !p.Ignored))
if (property.UnderlyingName == EsiObjName && property.PropertyType == typeof(string))
var esiValue = (string)property.ValueProvider.GetValue(value);
if (!string.IsNullOrEmpty(esiValue))
WriteValueDelimiter(writer);
writer.WriteWhitespace("\n");
writer.WriteRaw(esiValue);
lastWasEsiProperty = true;
var propertyValue = property.ValueProvider.GetValue(value);
if (propertyCount == 1 && lastWasEsiProperty)
WriteValueDelimiter(writer);
writer.WritePropertyName(property.PropertyName);
serializer.Serialize(writer, propertyValue);
lastWasEsiProperty = false;
static void WriteValueDelimiter(JsonWriter writer)
var args = new object[0];
writer.GetType().GetMethod("WriteValueDelimiter", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Invoke(writer, args);
public override bool CanConvert(Type objectType)
return typeof(T).IsAssignableFrom(objectType);
public override bool CanRead { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
throw new NotImplementedException();
public class mApiResponseClass
public int value { get; set; }
public string string1 { get; set; }
public string EsiObj { get; set; }
public List<string> Song { get; set; }
public class mApiResponseClassEsiFirst
public string EsiObj { get; set; }
public int value { get; set; }
public string string1 { get; set; }
public List<string> Song { get; set; }
public class mApiResponseClassEsiLast
public int value { get; set; }
public string string1 { get; set; }
public List<string> Song { get; set; }
public string EsiObj { get; set; }
public class mApiResponseClassEsiOnly
public string EsiObj { get; set; }
public static void Test()
var esiObj = new mApiResponseClass
EsiObj = @"<esi:include src=""/something"" />",
Song = new List<string> { "I am a small API","all i do is run","but from who?","nobody knows" },
var esiFirst = new mApiResponseClassEsiFirst
EsiObj = @"<esi:include src=""/something"" />",
Song = new List<string> { "I am a small API", "all i do is run", "but from who?", "nobody knows" },
var esiOnly = new mApiResponseClassEsiOnly
EsiObj = @"<esi:include src=""/something"" />",
var esiLast = new mApiResponseClassEsiLast
EsiObj = @"<esi:include src=""/something"" />",
Song = new List<string> { "I am a small API", "all i do is run", "but from who?", "nobody knows" },
TestSimpleAndUnquoted(esiObj);
TestSimpleAndUnquoted(esiFirst);
TestSimpleAndUnquoted(esiLast);
TestSimpleAndUnquoted(esiOnly);
Console.WriteLine("Done tests");
private static void TestSimpleAndUnquoted<mApiResponseClass>(mApiResponseClass esiObj)
TestWithoutNameQuoting(esiObj);
private static void TestSimple<mApiResponseClass>(mApiResponseClass obj)
Console.WriteLine("Serializing an instance of {0}:", obj);
var settings = new JsonSerializerSettings
Converters = { new EsiObjConverter<mApiResponseClass>() },
var json = JsonConvert.SerializeObject(obj, Formatting.Indented, settings);
private static void TestWithoutNameQuoting<mApiResponseClass>(mApiResponseClass obj)
Console.WriteLine("Serializing an instance of {0} without name quoting:", obj);
var settings = new JsonSerializerSettings
Converters = { new EsiObjConverter<mApiResponseClass>() },
var stringWriter = new StringWriter();
using (var writer = new JsonTextWriter(stringWriter))
writer.QuoteName = false;
writer.Formatting = Formatting.Indented;
JsonSerializer.CreateDefault(settings).Serialize(writer, obj);
var json = stringWriter.ToString();
private static void TestNested<mApiResponseClass>(mApiResponseClass obj)
Console.WriteLine("Testing nested serialization of {0}:", obj);
var settings = new JsonSerializerSettings
Converters = { new EsiObjConverter<mApiResponseClass>() },
var json = JsonConvert.SerializeObject(new { data = new [] { obj }}, Formatting.Indented, settings);
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: ");