Binding complex object to request DTO

926 views
Skip to first unread message

Diego

unread,
May 15, 2011, 10:18:50 PM5/15/11
to ServiceStack .NET Open Source REST Web Services Framework
I have been using ServiceStack over the last couple of months and it
is a pleasure to use. The speed, simplicity and elegant (minimalist)
design attracted me right away. I hate code-gen and the clean POCO's
make reusability and simple dependencies easy.

Now to the issue. I am having trouble binding a post method to a
complex object on the request DTO. I created the following simple
example to illustrate.

//Request DTO
[DataContract]
public class GeoInfo
{
[DataMember]
public string AppToken { get; set; }

[DataMember]
public int OrderId { get; set; }

[DataMember]
public GeoPoint GeoCode { get; set; }
}

[Serializable]
public class GeoPoint
{
public long t { get; set; }
public decimal latitude { get; set; }
public decimal longitude { get; set; }
}

//Response DTO
public class GeoInfoResponse : IHasResponseStatus
{
public string Result { get; set; }
public ResponseStatus ResponseStatus { get; set; } //Where
Exceptions get auto-serialized
}

public class GeoService : RestServiceBase<GeoInfo>
{
public override object OnPost(GeoInfo request)
{
return new GeoInfoResponse
{
Result = "Incoming Geopoint: Latitude="
+ request.GeoCode.latitude.ToString()
+ " Longitude="
+ request.GeoCode.longitude.ToString()
};
}
}


As you can see, I am expecting a GeoPoint on the request with the
property name GeoCode.
The following javascript should create the desired json for the ajax
request.

$(function () {

var dt = new Date();
var etime = dt.getTime();

var jdata = {
"AppToken": "TEST123",
"OrderId": 1,
"GeoCode": {
"t": etime,
"latitude": 32.81434,
"longitude": -80.3432221
}
};

$.post("/geoinfo", jdata, function (data)
{ alert(data.Result); }, "json");

)};

However, the incoming GeoCode object is null.
Do I have to implement my own binding for any type of nested objects?
Any help is greatly appreciated.

Thanks to Demis and Ethan for their dedication and effort on this
group.

Regards,
Diego.

Demis Bellot

unread,
May 16, 2011, 11:11:28 AM5/16/11
to servic...@googlegroups.com
Hi Diego,

Yeah ServiceStack accepts nested JSON no problem. 

In times when you're having interoperability problems I suggest that you have Fiddler open (which is very easy to use) so you can see exactly what's going on. Also the Fiddler packet trace is more valuable in diagnosing problems since it holds the 'empirical truth' of what's happening on the wire even more than the source code since as can be seen in this example, where the source code does something different than what you're expecting.

The problem with your service is that jQuery by default sends your data via key value pairs (i.e. application/x-www-form-urlencoded) so you need to serialize it to JSON yourself if you want jQuery to send JSON instead of key value pairs.
I've modified your POST example to send JSON data:

$.post("geoinfo", JSON.stringify(jdata),
  function (data) {
    alert(data.Result);
  },
"json");

This is the longer form of how you can POST json data using jQuery which lets you toggle different parts of the ajax request:

$.ajax({
  url: "geoinfo",
  type: "POST",
  contentType: "application/json",
  accept: "application/json",
  dataType: "json",
  data: JSON.stringify(jdata),
  success: function (data) {
    alert(data.Result);
  }
});

It seems that you have some DTO's are decorated with [DataContract] and some not. Note: [DataContract] is optional, and it just allows you to control some of the XML serialized output (or should you wish control which properties are serialized). Also [Serializable] doesn't mean anything in ServiceStack, the only library which requires it is the memcached ICacheClient since it uses the Binary Formatter internally, so if you aren't using/needing it I think you should consider dropping it.

Hope this helps.

Regards,

Reply all
Reply to author
Forward
0 new messages