JSONReturnBinder

24 views
Skip to first unread message

Gabriel Mancini de Campos

unread,
Jun 20, 2009, 6:06:31 PM6/20/09
to Castle Project Users
Hi Again Guys,


Sorry my flood but i had a trouble, with jquery integration...
In my View i have some like this:

$('#btnList').click(function() {

ajaxOption = $.extend(ajaxOption, {
url: 'MyAction.mvc',
sucess: function(return) {
$('#txtDate').val(return.Date); <---- set datetime
value to a text field
},
type: "Get"
});

$.ajaxSetup(ajaxOption);
$.ajax();
});

my Action like this:

[AccessibleThrough(Verb.Post)]
[Rescue(typeof(RescueController), "JsonError")]
[return: JSONReturnBinder]
public Customer MyAction() {
return repository.FindAll()[0];
}

and the return Json like this:

[{"Campanha":"3","Canal":{"Descricao":"Loja","Id":1},"Data":"\/Date
(1245531858000-0300)\/" ,"Numero":"123412","NumeroParcelas":
5,"PlanoFinanciamento":{"Descricao":"Plano 1","Id":1},"Produto":
{"Descricao":"Mastercard","Id":1}]

"Data":"\/Date(1245531858000-0300)\/" <------------- WTF!!!

any one knows how i show the true date????

Mauricio Scheffer

unread,
Jun 20, 2009, 6:30:54 PM6/20/09
to Castle Project Users
JSONReturnBinder is using the default Date encoding from JSON.Net (see
http://james.newtonking.com/archive/2009/02/20/good-date-times-with-json-net.aspx
)
It would be cool if JSONReturnBinder accepted an enum or something to
change this behavior and use JavaScriptDateTimeConverter instead...
maybe you could implement it and send a patch? ;-)

Rationale for this encoding: http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx

On Jun 20, 7:06 pm, Gabriel Mancini de Campos

Gabriel Mancini de Campos

unread,
Jun 21, 2009, 3:51:27 PM6/21/09
to Castle Project Users
OK i will implmement is ..

but tomorrow i realy need a solution.
any one knows a alternative resolution ???


On 20 jun, 19:30, Mauricio Scheffer <mauricioschef...@gmail.com>
wrote:
> JSONReturnBinder is using the default Date encoding from JSON.Net (seehttp://james.newtonking.com/archive/2009/02/20/good-date-times-with-j...

Mauricio Scheffer

unread,
Jun 21, 2009, 8:28:41 PM6/21/09
to Castle Project Users
You could either search for "\\/Date\((\d+)\)\\/" and replace with
"new Date($1)" like Bertrand's post suggests, or code your own
IReturnBinder like this one: http://pastebin.com/m737a0bff (completely
untested!)

On Jun 21, 4:51 pm, Gabriel Mancini de Campos

John Simons

unread,
Jun 21, 2009, 9:13:41 PM6/21/09
to Castle Project Users
Gabriel,

That is a javascript Date object.
If you want to format the date object you can call any on the methods
of the javascript Date object, eg:

Date myDate = new Date(1245531858000-0300);
alert(myDate.toString());

Have a look at this one http://www.w3schools.com/jsref/jsref_obj_date.asp
to see what methods the javascript date object has.

Cheers
John

On Jun 21, 8:06 am, Gabriel Mancini de Campos

Mauricio Scheffer

unread,
Jun 21, 2009, 10:28:00 PM6/21/09
to Castle Project Users
It contains date information, but it's not a Date object. You have to
parse it and convert it to a Date object in order to use it, unlike
other types in JSON.

On Jun 21, 10:13 pm, John Simons <johnsimons...@yahoo.com.au> wrote:
> Gabriel,
>
> That is a javascript Date object.
> If you want to format the date object you can call any on the methods
> of the javascript Date object, eg:
>
> Date myDate = new Date(1245531858000-0300);
> alert(myDate.toString());
>
> Have a look at this onehttp://www.w3schools.com/jsref/jsref_obj_date.asp

John Simons

unread,
Jun 21, 2009, 10:41:59 PM6/21/09
to Castle Project Users
Have you tried to use the Json.NET library serialization attributes to
control the serialization of your dates? (Castle uses this library
internally)
Here is an example:
[JsonObject(MemberSerialization.OptIn)]
public class Person
{
// "John Smith"
[JsonProperty]
public string Name { get; set; }

// "2000-12-15T22:11:03"
[JsonProperty]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime BirthDate { get; set; }

// new Date(976918263055)
[JsonProperty]
[JsonConverter(typeof(JavaScriptDateTimeConverter))]
public DateTime LastModified { get; set; }

// not serialized
public string Department { get; set; }
}


You can read more http://james.newtonking.com/projects/json/help/SerializingJSON.html


On Jun 22, 12:28 pm, Mauricio Scheffer <mauricioschef...@gmail.com>
wrote:

John Simons

unread,
Jun 21, 2009, 10:47:05 PM6/21/09
to Castle Project Users
Yes you are right you have to do an eval:
$('#txtDate').val(eval(return.Date).toString()); <---- set datetime
value to a text field

On Jun 22, 12:28 pm, Mauricio Scheffer <mauricioschef...@gmail.com>
wrote:

Mauricio Scheffer

unread,
Jun 21, 2009, 11:49:10 PM6/21/09
to Castle Project Users
It can't be eval()'ed to a Date object with the default format. Only
when the JavaScriptDateTimeConverter is used.
Didn't know that json.net supported those attributes, nice tip!
However I'd prefer that the return binder could handle that, it would
be cleaner IMO...

John Simons

unread,
Jun 22, 2009, 12:09:40 AM6/22/09
to Castle Project Users
yeap, I've just checked my code and that is what I'm doing.
I think you are only left with one option, do not use
JSONReturnBinderAttribute and do the serialization yourself in the
action. That is what I ended up doing.

that said you can always contribute a patch or another option is to
create a suggestion in http://castle.uservoice.com

Cheers
John

On Jun 22, 1:49 pm, Mauricio Scheffer <mauricioschef...@gmail.com>

Jason Meckley

unread,
Jun 22, 2009, 9:43:28 AM6/22/09
to Castle Project Users
I cannot locate the article, but one alternative I read about is to
avoid the date serialization altogether by formatting the date to a
string before sending to the client. then you can easily
var date = new Date(result.DateAsString);
from the json result. or you can plug this into an input element. The
gist of the article was treat Dates like strings instead of dates. it
makes json and js easier to control.

On Jun 22, 12:09 am, John Simons <johnsimons...@yahoo.com.au> wrote:
> yeap, I've just checked my code and that is what I'm doing.
> I think you are only left with one option, do not use
> JSONReturnBinderAttribute and do the serialization yourself in the
> action. That is what I ended up doing.
>
> that said you can always contribute a patch or another option is to
> create a suggestion inhttp://castle.uservoice.com

Mauricio Scheffer

unread,
Jun 22, 2009, 10:19:31 AM6/22/09
to Castle Project Users
Take a look at the links I posted above, they explain the formats
currently in use and the pros and cons of each.
I wouldn't use other formats as it could hurt interoperability.

Mike Nichols

unread,
Jun 22, 2009, 11:32:18 AM6/22/09
to Castle Project Users
i wonder if date.js has something to help in this regard
http://www.datejs.com/

On Jun 22, 7:19 am, Mauricio Scheffer <mauricioschef...@gmail.com>
wrote:

Gabriel Mancini de Campos

unread,
Jun 23, 2009, 7:15:15 AM6/23/09
to Castle Project Users
thanks every one...

however because my target, i made something ugly.

public class JSJSONReturnBinderAttribute : JSONReturnBinderAttribute,
IReturnBinder
{



/// <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)
{

IsoDateTimeConverter jsonConverter = new
IsoDateTimeConverter
{
Culture = Thread.CurrentThread.CurrentCulture,
DateTimeFormat =
Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern,
DateTimeStyles = DateTimeStyles.AssumeLocal
};
// jsonSerializer.Converters.Add(new
JavaScriptDateTimeConverter());



StringWriter sw = new StringWriter
(CultureInfo.InvariantCulture);
JsonSerializer jsonSerializer = new JsonSerializer
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling =
NullValueHandling.Include,
};

// jsonSerializer.Converters.Add(new
JavaScriptDateTimeConverter());


jsonSerializer.Converters.Add(jsonConverter);

using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = (Newtonsoft.Json.Formatting)
Formatting.None;
jsonSerializer.Serialize(jsonWriter, returnValue);
}

if (returnValue == null)
return returnType.IsArray ? "[]" : "{}";

return sw.ToString();
}
}


On 22 jun, 12:32, Mike Nichols <nichols.mik...@gmail.com> wrote:
> i wonder if date.js has something to help in this regardhttp://www.datejs.com/

Alex Henderson

unread,
Jun 23, 2009, 9:19:20 PM6/23/09
to castle-pro...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages