using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Newtonsoft.Json;
namespace jMVCHelper
{
///
/// Utility class for serializing an object to JSON format using a single, shared JsonSerializer object
/// into which you can register JsonConverters
///
internal class JsonSerializationHelper
{
private JsonSerializer m_Serializer;
public JsonSerializationHelper()
{
m_Serializer = new JsonSerializer();
m_Serializer.Converters.Add(new DateTimeUTCConverter());
}
public void RegisterJsonConverter(JsonConverter converter)
{
m_Serializer.Converters.Add(converter);
}
public void WriteSerialized(object obj, TextWriter writer)
{
if (obj == null)
writer.Write("null");
else
m_Serializer.Serialize(writer, obj);
}
public string Serialize(object obj)
{
if (obj == null)
return null;
else
{
StringWriter sw = new StringWriter();
m_Serializer.Serialize(sw, obj);
return sw.ToString();
}
}
public object Deserialize(JsonReader reader, Type type)
{
if (type != null)
return m_Serializer.Deserialize(reader, type);
else
return m_Serializer.Deserialize(reader);
}
public object Deserialize(string json, Type type)
{
if (string.IsNullOrEmpty(json))
return null;
else
{
if (type == null)
throw new ArgumentNullException("type");
JsonReader reader = new JsonReader(new System.IO.StringReader(json));
if (typeof(JavaScriptObject).IsAssignableFrom(type)) // Don't specify a type if it's really a JS object, otherwise Json.net throws errors
return m_Serializer.Deserialize(reader);
else
return m_Serializer.Deserialize(reader, type);
}
}
///
/// To avoid timezone problems, dates will be represented in UTC in Javascript
///
private class DateTimeUTCConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value)
{
writer.WriteValue(((DateTime)value).ToUniversalTime());
}
public override object ReadJson(JsonReader reader, Type objectType)
{
if (reader.Value is string)
return DateTime.Parse((string)reader.Value);
else if (reader.Value is DateTime)
return new DateTime(((DateTime)reader.Value).Ticks, DateTimeKind.Utc);
else
throw new NotImplementedException("DateTimeUTCConverter can't deserialize value of type " + reader.ValueType.FullName);
}
public override bool CanConvert(Type objectType)
{
return typeof(DateTime).IsAssignableFrom(objectType);
}
}
}
}