How to transfer a complex model from client to server?

I have some “Foo” data that I want to transfer from the browser to the server and get predicted statistics based on the information contained in the foo file.

$.ajax({ type: 'GET', url: "/api/predictedStats/", data: "foo=" + ko.toJSON(foo, fooProperties), contentType: 'application/json; charset=utf-8', dataType: 'json', success: function(data) { return _this.viewModel.setPredictedStats(data); }, error: function(jqXHR, statusText, errorText) { return _this.viewModel.setErrorValues(jqXHR, errorText); } }); 

I created a predicted statistics controller and get a method that takes a Foo argument.

 public class PredictedStatsController : ApiController { public PredictedStats Get(Foo foo) { return statsService.GetPredictedStats(foo); } } 

Holding a breakpoint in the Get method, I see that the Foo object is always zero. There are no errors caused by the webapi trace log, only the following lines.

 WEBAPI: opr[FormatterParameterBinding] opn[ExecuteBindingAsync] msg[Binding parameter 'foo'] status[0] WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Type='foo', content-type='application/json; charset=utf-8'] status[0] WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Value read='null'] status[0] 

I have no problem sending data through a message to the Foo controller to create a Foo object on the server, so I can say that nothing happened with the json client created.

Looking at the violinist, the resulting Get is as follows, where jsondata is the foo object.

 GET /api/predictedStats?foo={jsondata} HTTP/1.1 

Is this possible, or am I doing it all wrong?

Thanks neil


EDIT: I feel I almost got this working with the following

 public PredictedStats Get([FromUri]Foo foo) { return statsService.GetPredictedStats(foo); } 

The foo object returned, but the Foo properties were not correctly populated.


At the same time, I resorted to using POST with almost identical data, just dropping "foo =", and this works fine.

I'm not sure whether to use POST or GET in this case, but that would be interesting to know.


I also found this http://bugs.jquery.com/ticket/8961 , which seems to suggest that you cannot attach the body to a GET request with jquery, so POST is probably the only reasonable option

+8
javascript jquery c # ajax asp.net-web-api
source share
1 answer

You almost got there :)

When you use [FromUri] (which you should use for "complex" objects, because by default the Web API does not "bind" complex objects, it always looks for them to deserialize from the body), you do not need pass param= in Uri - you just pass the value members as query string parameters. This is 'member1=value&member2=value' - where member1 and member2 are members of Foo .

Note that there is no “error” in jQuery, while the HTTP specification does not prohibit the request body, it is likely that the browser does (and if this is the case, jQuery cannot send it), and this is more than the probability that the server will never will read it anyway. It is simply not customary to practice. In addition, it also has interesting caching problems, since the browser will not cache POST, PUT, DELETE, etc., but it will cache GET if the response headers do not prohibit this - this can have serious side effects for the client application. I recommend that you look at this SO: HTTP GET with the request body for more information and useful links on this topic.

Similarly, when using jQuery - you also do not need to convert the object to JSON - just pass the javascript object in the data member of the parameters, and jQuery will turn it into the correct format.

Or the Web API must understand the format that jQuery passes to it as.

+6
source share

All Articles