1

I am facing a problem inside my ASP.NET MVC 5 application.

I am passing the following JSON to a third party API, which include a password value :-

"{\"operation\":{\"Details\":{\"RESOURCENAME\":\"123\",\"ACCOUNTNAME\":\"test45\",\"PASSWORD\":\"123%456t\",\"createAccount\":{\"operation\":{\"Details\":{\"ACCOUNTLIST\":[]}}}}"

Now the problem is that inside the 3rd party system the API will save the password 123%456t as 123E6t.

Can anyone advice on this please? Is this a problem inside the 3rd party API or a problem that I need to handle from my side?

John John
  • 1
  • 72
  • 238
  • 501

1 Answers1

4

That is definitely a server side problem. The percent sign is not a special character in JSON.

Deserializing your JSON with JSON.NET yields the expected result: 123%456t.

I think they call HttpUtility.UrlDecode or something similar on the JSON as a whole or a part of it, since that yields 123E6t.

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 1
    So, as a forward-preventative measure, would you say to try and `UrlEncode()` the JSON, thus to counteract the possible `UrlDecode` the other end? – Geoff James Jul 26 '16 at 14:08
  • 1
    That sounds dangerous, but it is worth the try if they don't cooperate. – Patrick Hofman Jul 26 '16 at 14:08
  • 1
    Noted. Just out of interest, I guess Newtonsoft's `JsonConvert` would output the same result? – Geoff James Jul 26 '16 at 14:11
  • @PatrickHofman so you mean it is a problem inside the 3rd party API ? now i am using JSON.net to construct my above json object.. – John John Jul 26 '16 at 14:11
  • Yes, I do. @johnG Your JSON looks okay. Are you sure you don't wrap it yourself? – Patrick Hofman Jul 26 '16 at 14:12
  • @PatrickHofman now when i pass the password as 500%600 it will be saved as 500`0 so not sure if i can do any work around for this ? – John John Jul 26 '16 at 14:20
  • @PatrickHofman so can you advice if my above json object is constructed correctly ? is so then i need to contact the 3rd party company to fix the problem ? – John John Jul 26 '16 at 14:37
  • 1
    As said before "Yes, I do. @johnG Your JSON looks okay. Are you sure you don't wrap it yourself?" – Patrick Hofman Jul 26 '16 at 14:38
  • @PatrickHofman I do not wrap it by my self... i use JSON.Net .... to serialize and deserialze the josn object – John John Jul 26 '16 at 16:23
  • @GeoffJames can you please advice why i need to use UrlEncode() ?? and is this a problem from my side or from the 3rd party api side ? – John John Jul 26 '16 at 16:58
  • @PatrickHofman now generally speaking is decoding the received json a correct approach to follow ? i mean seems from the result we are getting that the 3rd part API is decoding the json i am sending .. so is decoding the passed json object a correct approach from the 3rd part API ??? and should i be encoding the passed json (i do not think so)?? – John John Jul 26 '16 at 17:35
  • 1
    @johnG - I should imagine that the issue is being caused at the 3rd party API's end, like Patrick has already pointed out - with the possibility alluded to in this answer, it might be worth trying `var encodedJson = WebUtility.UrlEncode(json);` to see if it remedies the problem - if so, you know that the 3rd party is `UrlDecode()`ing the string the other end. This is not, however a good practice. Best solution would be to speak to the developers who work on the API to see what their suggestion is etc. – Geoff James Jul 26 '16 at 18:09
  • @GeoffJames but the problem with Url.Encode is that some values such as password@123 will be populated correctly inside the 3rd party system.. so if i am going to encode the password@123 it will no longer work is this correct ? as it will be populated correctly out of the box .. – John John Jul 26 '16 at 18:18
  • @GeoffJames now you mentioned "you know that the 3rd party is UrlDecode()ing the string the other end." but according to the API standards ,, should the 3rd party API decode the json i am sending ??? – John John Jul 26 '16 at 18:24
  • 1
    AFAIK the `@` character does not need to be encoded, and is fine as-is - which might explain why "`password@123`" works OK. I'm not aware of any "API Standards" (best practices, maybe - but it's not mentioned anywhere I can see). The only best-fit hard-and-fast rule for API devs to follow is to document their API to the hills, so that users that consume it know exactly how to compile request and send/receive data. Ergo, ensure that it's not in some tiny print in their documentation, and speak to one of them if possible, to see what's going on :) – Geoff James Jul 26 '16 at 18:40
  • @GeoffJames i totally agree with you , i send them an email with all the cases i faced ,, hopefully to get a respond from them soon.. But since there is not a standard for the API (generally speaking) ,, so it is not a surprise that they might be expecting the json in encoded format ,, although inside their API documentation they never mention this. this is correct ? – John John Jul 26 '16 at 21:55
  • I hope they will sort this out for you. Good luck! – Patrick Hofman Jul 26 '16 at 22:06
  • @PatrickHofman they replied back that i need to set the content type header as url encoded format which should fix them.currently i am using the following webclient class to upload the json object :- using (WebClient wc = new WebClient()) { string url = currentURL + "resources?AUTHTOKEN=" + pmtoken; Uri uri = new Uri(url); wc.Headers.Add(HttpRequestHeader.ContentType, "application/json"); crudoutput = wc.UploadString(uri, "INPUT_DATA=" + data); } – John John Jul 27 '16 at 15:33
  • I don't understand what they expect. The code looks okay. – Patrick Hofman Jul 27 '16 at 17:43
  • Why do you do `INPUT_DATA=`? – Patrick Hofman Jul 27 '16 at 17:44
  • @PatrickHofman this is how the json object should be formatted .. what they expect is to have my above json object to be url encoded ,,, such as wheh i encode using the following website http://meyerweb.com/eric/tools/dencoder/ – John John Jul 27 '16 at 21:20
  • So it isn't a JSON request, it is a form encoded request. Then you should indeed use `HttpUtility.UrlEncode` around the JSON part. – Patrick Hofman Jul 27 '16 at 21:21
  • @PatrickHofman it is a Post request to the API as the json object i am sending is actually used to add a new resource inside the API ... so yes it is a Post request.. this is the API am talking about https://www.manageengine.com/products/passwordmanagerpro/help/restapi.html#createresource – John John Jul 27 '16 at 21:24
  • @PatrickHofman now i try the following var encodedJson = WebUtility.UrlEncode(data); then i am going to send the encodedJson instead of sending the data object directly ,, and now i can see that my data is being populated correctly inside the API where 500%600 is going to be saved as 500%600 ... so should this be fine ? – John John Jul 27 '16 at 21:30
  • @PatrickHofman but on your first comments you mentioned the following about using UrlEncode() "That sounds dangerous, but it is worth the try if they don't cooperate." ,, so can i know why it is sound dangerous ? – John John Jul 28 '16 at 12:32
  • @GeoffJames now based on your suggestion i used <> and i was able to send values such as 123%456t to the 3rd part api .. but you mentioned that "This is not, however a good practice." so can you mention why you consider url encoding my json is not a good practice ? now when i contact the 3rd party company they mentioned that i need to "set the content type header as url encoded format " ... – John John Jul 28 '16 at 12:36
  • @johnG Just to clarify - what I meant was, that it doesn't seem to be convention that I've seen a lot of APIs use. This doesn't mean to say that it shouldn't be done - at the very least it *needs* to be documented somewhere with the API documentation to specify what is necessary when compiling and sending request. Glad you've got it working :) – Geoff James Jul 28 '16 at 12:52
  • @GeoffJames now they mentioned that i do not need to encode the json object manually using WebUtility.UrlEncode(json) ... i need only to set the content type header as url encoded format .. but not sure how i can do this operation inside WebClient UploadString ?? – John John Jul 28 '16 at 15:05
  • 1
    @johnG Off the top of my head it would be something like `client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");` when you've created the `client` – Geoff James Jul 28 '16 at 15:09
  • @GeoffJames i tried this but did not work, as i will get the same problem that the data will be saved wrongly inside the 3rd party API.. i open another question regarding this http://stackoverflow.com/questions/38640292/unable-to-encode-my-json-object-insdie-my-webclient-uploadstring-using-headers – John John Jul 28 '16 at 15:12