Skip to content

Instantly share code, notes, and snippets.

@JoeRobich
Created April 7, 2012 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoeRobich/2331300 to your computer and use it in GitHub Desktop.
Save JoeRobich/2331300 to your computer and use it in GitHub Desktop.
Abstraction to allow System.Web.Extension JavaScriptConveters to run as JSON.Net JsonConverters.
using System;
using System.Collections.Generic;
using Serialization.Text
namespace Drawing.Geometry
{
public class GeometryConverter : IJsonConverter
{
public object Deserialize(IDictionary<string, object> dictionary, Type type, IJsonSerializer serializer)
{
Geometry geometry = null;
if (dictionary.ContainsKey("x"))
{
geometry = serializer.ConvertToType<MapPoint>(dictionary);
}
else if (dictionary.ContainsKey("points"))
{
geometry = serializer.ConvertToType<Multipoint>(dictionary);
}
else if (dictionary.ContainsKey("paths"))
{
geometry = serializer.ConvertToType<Polyline>(dictionary);
}
else if (dictionary.ContainsKey("rings"))
{
geometry = serializer.ConvertToType<Polygon>(dictionary);
}
else if (dictionary.ContainsKey("xmin"))
{
geometry = serializer.ConvertToType<Envelope>(dictionary);
}
return geometry;
}
public IDictionary<string, object> Serialize(object obj, IJsonSerializer serializer)
{
return serializer.Deserialize<Dictionary<string, object>>(serializer.DefaultSerialize(obj));
}
public IEnumerable<Type> SupportedTypes
{
get { return new Type[] { typeof(Geometry) }; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Serialization.Text
{
public interface IJsonConverter
{
object Deserialize(IDictionary<string, object> dictionary, Type type, IJsonSerializer serializer);
IDictionary<string, object> Serialize(object obj, IJsonSerializer serializer);
IEnumerable<Type> SupportedTypes { get; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Serialization.Text
{
public interface IJsonSerializer
{
void RegisterConverters(IEnumerable<IJsonConverter> converters);
T ConvertToType<T>(IDictionary<string, object> dictionary);
T Deserialize<T>(string input);
string Serialize(object obj);
string DefaultSerialize(object obj);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace Serialization.Text
{
public class NewtonsoftJsonConverter : JsonConverter
{
private IJsonConverter _converter = null;
private IJsonSerializer _serializer = null;
public NewtonsoftJsonConverter(IJsonSerializer serializer, IJsonConverter converter)
{
_serializer = serializer;
_converter = converter;
}
public override bool CanConvert(Type objectType)
{
foreach (Type type in _converter.SupportedTypes)
if (type.IsAssignableFrom(objectType))
return true;
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object value = ReadValue(reader);
if (value == null)
return value;
if (!(value is IDictionary<string, object>))
throw new Exception("Expected dictionary but found a list");
value = _converter.Deserialize((IDictionary<string, object>)value, objectType, _serializer);
return value;
}
private object ReadValue(JsonReader reader)
{
while (reader.TokenType == JsonToken.Comment)
{
if (!reader.Read())
throw new Exception("Unexpected end.");
}
switch (reader.TokenType)
{
case JsonToken.StartObject:
return ReadObject(reader);
case JsonToken.StartArray:
return ReadList(reader);
default:
if (IsPrimitiveToken(reader.TokenType))
return reader.Value;
throw new Exception(string.Format("Unexpected token when converting to Dictionary: {0}", reader.TokenType));
}
}
private bool IsPrimitiveToken(JsonToken token)
{
switch (token)
{
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Undefined:
case JsonToken.Null:
case JsonToken.Date:
case JsonToken.Bytes:
return true;
default:
return false;
}
}
private object ReadList(JsonReader reader)
{
IList<object> list = new List<object>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Comment:
break;
default:
object v = ReadValue(reader);
list.Add(v);
break;
case JsonToken.EndArray:
return list;
}
}
throw new Exception("Unexpected end.");
}
private object ReadObject(JsonReader reader)
{
IDictionary<string, object> dictionary = new Dictionary<string, object>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string propertyName = reader.Value.ToString();
if (!reader.Read())
throw new Exception("Unexpected end.");
object v = ReadValue(reader);
dictionary[propertyName] = v;
break;
case JsonToken.Comment:
break;
case JsonToken.EndObject:
return dictionary;
}
}
throw new Exception("Unexpected end.");
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IDictionary<string, object> dictionary = _converter.Serialize(value, _serializer);
serializer.Serialize(writer, dictionary);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace Serialization.Text
{
public class NewtonsoftJsonSerializer : IJsonSerializer
{
private JsonSerializerSettings _settings = new JsonSerializerSettings();
public void RegisterConverters(IEnumerable<IJsonConverter> converters)
{
foreach (IJsonConverter converter in converters)
_settings.Converters.Add(new NewtonsoftJsonConverter(this, converter));
}
public T ConvertToType<T>(IDictionary<string, object> dictionary)
{
string intermediate = JsonConvert.SerializeObject(dictionary);
T value = JsonConvert.DeserializeObject<T>(intermediate);
return value;
}
public T Deserialize<T>(string input)
{
return JsonConvert.DeserializeObject<T>(input, _settings);
}
public string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj, Formatting.None, _settings);
}
public string DefaultSerialize(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment