I am attempting to send updates to the service using the following restSettings:
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
The service says its a bad request. Using an HTTP proxy I am able to look at the body of the request, which is JSON:
I would have expected:
id=20026&name=John%20Smith
Does the grid support contentType application/x-www-form-urlencoded? If so, any guesses what I'm doing wrong?
Thanks!
Hello Matthew,
We don't provide automatic serialization in the format specified in the content type (it's always json). However, you can specify a serializer of your own. Your requirements should be achievable with the following:
restSettings: { update: ... , remove: ... , create: ... , contentSerializer: function (obj) { var str = []; for (var p in obj) if (obj.hasOwnProperty(p)) { str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); } return str.join("&"); } }
Credit for the function goes to this SO thread .
I hope this helps!
Best regards,
Stamen Stoychev
Followup question that is still on topic (I think.)
I am using contentType: x-www-form-urlencoded, as mentioned earlier. This works fine for updates (PUT). But for deletes (DELETE) the grid is sending Content-Type: text/plain for some reason. This is rejected by the service (though technically it shouldn't matter as there are no fields being passed to the DELETE.)
: text/plain
Here are my restSettings:
restSettings: { contentType: "application/x-www-form-urlencoded; charset=UTF-8", contentSerializer: iggridUrlEncode, create: { url: env_constants.DATASERVICES_URL + "/ar_invoices/" }, update: { url: env_constants.DATASERVICES_URL + "/ar_invoices/" }, remove: { url: env_constants.DATASERVICES_URL + "/ar_invoices/" } }
Seems to me all three URL's should respect the contentType setting. Any suggestions?
1. I am going to start a new forum thread for the DELETE contentType problem. It's independent of this discussion.
2. I strongly suspect the date serialization problem is a grid bug. Let me know if Infragistics needs more information from me. I've worked around it for now by explicitly checking for the C# date string, and converting it to the JS Date object I was expecting. If I'm right, this problem potentially effects anyone who writes a contentSerializer and has an editable date column that can start out blank.
Thanks,
Matt
Hi Matthew,
The empty string which is the body of a DELETE request is not a valid JSON string, which is why the content type is overridden to text/plain.
As for the date serialization, the date does get stored as a date object on the client, however, what you are processing in your serialization function is the transaction object that would be sent to the server and at that point dates are already serialized to the Microsoft's format /Date(ticks)/ . You could work this around with something like:
var date = new Date(parseInt(str.substr(6)));
Which would give you the original date to process as you like.
The date being sent like this is mostly a consistency issue with WebAPI which uses JSON.Net as a serializer and JSON.Net uses ISO 8601 by default. This means your GET requests give you dates in ISO 8601 but the grid emits PUT ones in /Date(ticks)/. JSON.Net should still be able to deserialize them though. Are you seeing something else?
Anyhow, I agree we can improve this and allow users to choose the format their dates are sent to the server. I'll let you know once we have a solid item in our tracking system that you can get notified for updates on.
Stamen,
Yes, all the discussion has been interesting and helpful. The support ticket is appreciated, and I will keep an eye on the release notes.
We are not blocked, thanks to the re-serialization workaround we both came up with. (Thanks for double-checking.)
Regards,
After discussing this internally, we think we can improve the handling of date objects both on the client and when sending them to a server. I logged multiple items with the ideas that came up and one bug with Development ID of 203551 that I linked to a private case I opened on your behalf (CAS-158597-W2X0R5). This one is about the automatic serialization upon transaction creation which is probably the issue that's affecting your application the most. For the other improvements (that will also involve API changes) you could follow the release notes of future versions.
I hope the workarounds that were discussed in these threads helped and you are not blocked from developing your application further. If you have other issues or concerns, please don't hesitate to contact me.
It's questionable what the correct content type is for an empty body. [..] Maybe there is a better solution that eluded us last time we tackled this.
Just a thought, but maybe allow the user to override the contentType separately for create, update, and remove. This wouldn't break any legacy behavior (which ideally would be mentioned to the documentation.) Something like:
restSettings: { create: { url: env_constants.DATASERVICES_URL + "/ar_invoices/", contentType: "application/x-www-form-urlencoded; charset=UTF-8" }, update: { url: env_constants.DATASERVICES_URL + "/ar_invoices/", contentType: "application/x-www-form-urlencoded; charset=UTF-8" }, remove: { url: env_constants.DATASERVICES_URL + "/ar_invoices/", contentType: "application/x-www-form-urlencoded; charset=UTF-8" } }
(I admit, it feels like overkill given that create and update are 99% likely to be the same. But I like it better than adding contentTypeForRemove, or a boolean keepContentTypeForRemove.)
Thank you for all your input!
My pleasure. You've been very responsive, even for bugs that were clearly mine. Most appreciated.
I don't know where my mind was when writing the comment on DELETE. Of course you are not sending JSON.
It's questionable what the correct content type is for an empty body. We may be a bit too strict overriding anything to text/plain in this regard. The code that's responsible is a part of a bug fix though so there were definitely cases of servers having issues receiving something else for content type. I'll have to dig this up a bit more. Maybe there is a better solution that eluded us last time we tackled this.
Thank you for all your input! It's always nice to get new perspectives from users utilizing different technologies that put our controls out of their comfort zones. Such cases are invaluable as means to improve the product.
I'm sending www-form-urlencoded, not JSON. Technically speaking, I think an empty string is valid.
But I think a larger question is, is it a strictly enforced web requirement that empty strings always be classified as text/plain? This service was written with JAX-RS (Jersey) which doesn't require that. So I'm guessing there are other services out there that also expect the "wrong" contentType on DELETE.
what you are processing in your serialization function is the transaction object that would be sent to the server and at that point dates are already serialized to the Microsoft's format /Date(ticks)/ .
Just to be clear: user-edited dates are serialized in this fashion, but unedited dates appear to be Date objects (not strings.) I think you understand that but I wanted to mention.
I understand that internally there is a difference between a user transaction and an unchanged value, but speaking purely as a user of the API it feels inconsistent to expose these differences to contentSerializer. If the user entered a valid date it makes more sense (to me) that all dates passed to the serializer be uniform.
JSON.Net should still be able to deserialize them though. Are you seeing something else?
We're not using .Net for this. This is a pure JQuery page hitting a Java service. The service supports several common date formats including ISO8601, but not /Date(ticks)/.
I agree we can improve this and allow users to choose the format their dates are sent to the server. I'll let you know once we have a solid item in our tracking system that you can get notified for updates on.
Thanks, I appreciate it!