How to structure a request for this JSON?

I have a 3rd party which will be posting information to me that looks as follows:

[  
   {  
      "speed":34.52,
      "time":1493590207074.66,
      "longitude":-122.23345363,
      "bearing":312.19,
      "location_type":"current",
      "latitude":37.42803355,
      "accuracy":5,
      "heading":312.19,
      "altitude":0,
      "altitudeAccuracy":-1
   }
]

How would I structure a request in C# for ServiceStack to serialize this correctly? I do not have any option to change the format of the body.

You can add custom deserializer to base.RequestBinders in AppHost.Configure. I assume that time field contains UNIX-time value so I modified serializer to handle this, in you case serializer will look something like this:

RequestBinders.Add(typeof(Dto), httpReq =>
{
    var json = httpReq.GetRawBody();

    using (JsConfig.BeginScope())
    {
        JsConfig<DateTime>.DeSerializeFn = time =>
            new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)
                .AddMilliseconds(Convert.ToDouble(time));

        return new Dto {Infos = JsonSerializer.DeserializeFromString<List<Info>>(json)};
    }
});

And here is DTO and service definition.

    [Route("/getinfos")]
    public class Dto : IReturn<string>
    {
        public List<Info> Infos { get; set; }
    }

    public class Info
    {
        public double Speed { get; set; }
        public DateTime Time { get; set; }
        public double Longitude { get; set; }
        public double Bearing { get; set; }
        public string Location_Type { get; set; }
        public double Latitude { get; set; }
        public int Accuracy { get; set; }
        public double Heading { get; set; }
        public double Altitude { get; set; }
        public double AltitudeAccuracy { get; set; }
    }

    public class InfoServices : Service
    {
        public object Any(Dto request)
        {
            return request.Dump();
        }
    }

I had no idea about the custom RequestBinders! That solves my issue thanks @xplicit.

JsConfig.BeginScope() doesn’t work with static JsConfig<T> configuration, so that wouldn’t be localized to the scope.

The way I’d handle this request is to have a Request DTO that inherits a List<Info> so it can accept an array of objects that’s contained in your JSON, e.g:

public class Info
{
    public double Speed { get; set; }
    public double Time { get; set; }
    public double Longitude { get; set; }
    public double Bearing { get; set; }
    public string Location_Type { get; set; }
    public double Latitude { get; set; }
    public int Accuracy { get; set; }
    public double Heading { get; set; }
    public double Altitude { get; set; }
    public double AltitudeAccuracy { get; set; }
}

[Route("/getinfos")]
public class Infos : List<Info>, IReturn<string> {}

I’d have the DTO contain a double and then manually convert the UnixTime like:

var time = request[0].Time.FromUnixTimeMs();

BTW I’ve created a live example on Gistlyn.

Yeah that custom serializer was causing me headaches, so I moved the logic to the controller.

However my main issue was how to serialize the JSON array. I did not know you could have a request DTO that inherited from List<x>. Great solution Demis!

1 Like