Announcement

Collapse
No announcement yet.

Direct cast of DateTime from server side JSON

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Marco
    started a topic Direct cast of DateTime from server side JSON

    Direct cast of DateTime from server side JSON

    Hi

    I have the following Dto class that I serialize on the server and deserialize on the client:

    namespace SVSExtranet.Web.Dto
    {
        [ObjectLiteral(ObjectCreateMode.Plain)] 
        public class CourseEventDto
        {
            public Guid Oid { get; set; }
    
            public Guid CourseOid { get; set; }
    
            public DateTime NetStart { get; set; }
    
            public DateTime NetEnd { get; set; }
    
            public string Material { get; set; }
    
            public string Trainer { get; set; }
    
            public string Location { get; set; }
        }
    }
    The problem is: After deserializing those objects, the DateTime properties don't contain real Date objects. Instead, they are parsed as JS strings with values like:
    "2016-10-11T14:30:00"

    I tried deserializing using both of the following techniques without success:

    return resp.As<CourseEventDto[]>(); //direct cast
    and

    return JSON.ParseAsArray<CourseEventDto>(xhr.ResponseText);
    What is the proper way to have complex types like DateTime deserialized?
    Thanks

    Marco

  • geoffrey.mcgill
    replied
    For future support requests, it would be best to post a Deck.NET sample demonstrating as much of your scenario as possible, but as simplified as possible. Remove all code that is not directly related to problem. This will avoid confusion and having to make assumptions about how you have your scenario configured.

    When serializing into JSON, all DateTime instances should always be serialized into strings, preferably into an ISO 8601 format, such as yyyy-MM-ddTHH:mm:ss.

    The JSON.Parse method does not automatically deserialize json date strings into DateTime (or Date) objects. This is a limitation (or feature?) of JSON.Parse, and not Bridge.

    The optional second parameter of the JSON.Parse Method is a reviver delegate. The reviver is used to test, convert and return the new value instance. The reviver can contain any custom logic to ultimately parse and return anything based on your custom logic

    More details on JSON.Parse and use of reviver functions can be found in the MDN documentation.

    The following sample demonstrates three similar techniques for parsing a json string into a real C# object using JSON.Parse. Each of the three Parse Methods deserialize the inbound json string into a fully rehydrated Person object.

    http://deck.net/b4580bb763bcfc11b5401834d3b3103e

    public class Program
    {
        public delegate object DateTimeReviverDelegate(string key, object value);
    
        public static void Main()
        {
            var json = @"{""name"": ""Frank"", ""birthDate"": ""1990-01-17""}";
    
            Log(Parse1(json));
            Log(Parse2(json));
            Log(Parse3(json));
        }
    
        public static void Log(Person person)
        {
            var date = person.BirthDate.ToString("M/d/yyyy");
    
            var tpl = $"Name: {person.Name} - DOB: {date}";
    
            Console.WriteLine(tpl);
        }
    
        public static Person Parse1(string json)
        {
            DateTimeReviverDelegate reviver = new DateTimeReviverDelegate(DateTimeReviver);
    
            // pass in a delegate reviver
            var person = JSON.Parse(json, reviver);
    
            // manually create the Person object and return
            return new Person
            {
                Name = person["name"].ToString(),
                BirthDate = (DateTime)person["birthDate"]
            };
        }
    
        public static Person Parse2(string json)
        {
            // pass in a delegate reviver instance, and return a Person   
            return JSON.Parse<Person>(json, new DateTimeReviverDelegate(DateTimeReviver));
        }
    
        public static Person Parse3(string json)
        {
            // configure an inline delegate reviver
            return JSON.Parse<Person>(json, delegate (string key, object value)
            {
                if (value is string)
                {
                    DateTime d;
    
                    if (DateTime.TryParse(value.ToString(), out d))
                    {
                        return d;
                    }
                }
    
                return value;
            });
        }
    
        public static object DateTimeReviver(string key, object value)
        {
            if (value is string)
            {
                DateTime dateValue;
    
                if (DateTime.TryParse(value.ToString(), out dateValue))
                {
                    return dateValue;
                }
            }
    
            return value;
        }
    }
    
    public class Person
    {
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
    }
    Hope this helps.
    Last edited by geoffrey.mcgill; 2017-01-18 @ 04:59 AM.

    Leave a comment:


  • samuelgrahame
    replied
    I am facing the following issue, It might be best to pass dates as longs.

    Leave a comment:

Working...
X