I did something similar last year for an ExtJS based RIA app...
[AttributeUsage(AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = false)]
public class EpochJsonReturnBinderAttribute : JSONReturnBinderAttribute
{
/// <summary>
/// Converts target object to its JSON representation
/// </summary>
/// <param name="returnType">Type of the target object</param>
/// <param name="returnValue">The target object</param>
/// <param name="serializer">The JSON serializer</param>
/// <returns></returns>
public override string GetRawValue(Type returnType, object returnValue, IJSONSerializer serializer)
{
if (returnValue == null)
return returnType.IsArray ? "[]" : "{}";
if (base.Properties == null)
return serializer.Serialize(returnValue, new DateConverter());
Type normalized = returnType.IsArray ? returnType.GetElementType() : returnType;
return serializer.Serialize(returnValue, new PropertyConverter(normalized, base.Properties), new DateConverter());
}
#region Nested type: DateConverter
class DateConverter : IJSONConverter
{
const string DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";
#region IJSONConverter Members
public void Write(IJSONWriter writer, object value)
{
string str;
if (value is DateTime)
{
var time = (DateTime) value;
str = time.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
}
else
{
var offset = (DateTimeOffset) value;
str = offset.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
}
writer.WriteValue(str);
}
public bool CanHandle(Type type)
{
return (type == typeof (DateTime) || type == typeof (DateTime?));
}
public object ReadJson(IJSONReader reader, Type objectType)
{
throw new NotImplementedException();
}
#endregion
}
#endregion
#region Nested type: PropertyConverter
class PropertyConverter : IJSONConverter
{
readonly List<PropertyInfo> properties = new List<PropertyInfo>();
readonly Type targetType;
public PropertyConverter(Type targetType, string propertyNames)
{
this.targetType = targetType;
foreach (string propertyName in propertyNames.Split(','))
{
PropertyInfo prop = targetType.GetProperty(propertyName);
if (prop == null)
{
throw new MonoRailException("Failed to JSON serialize object. " +
"Property " + propertyName + " could not be found for type " + targetType.FullName);
}
properties.Add(prop);
}
}
#region IJSONConverter Members
public void Write(IJSONWriter writer, object value)
{
writer.WriteStartObject();
foreach (PropertyInfo info in properties)
{
object propVal = info.GetValue(value, null);
writer.WritePropertyName(info.Name);
writer.WriteValue(propVal);
}
writer.WriteEndObject();
}
public bool CanHandle(Type type)
{
return type == targetType;
}
public object ReadJson(IJSONReader reader, Type objectType)
{
throw new NotImplementedException();
}
#endregion
}
#endregion