I have a .Net WCF Rest service returning Json to be consumed by an Android app.
In debug, the WCF service correctly has the return value (Json) as:
{"BaseLoyaltyPoints":1480,"BonusLoyaltyPoints":0,"BrandId":1414, [etc...] }
Also in debug, when it returns to Notepad, the return value has changed to:
{\"BaseLoyaltyPoints\":1480,\"BonusLoyaltyPoints\":0,\"BrandId\":1414, [etc...] }
And when it gets to my Android app, it has become:
{\\"BaseLoyaltyPoints\\":1480,\\"BonusLoyaltyPoints\\":0,\\"BrandId\\":1414, [etc...] }
This is the boilerplate code I am using to serialize the Json:
Dim stream1 As MemoryStream = New MemoryStream
Dim ser As DataContractJsonSerializer = New DataContractJsonSerializer(GetType(FullProduct))
ser.WriteObject(stream1, Me)
Dim _json As String = Encoding.UTF8.GetString(stream1.ToArray())
stream1.Close()
The Android code to get the Json is:
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(getString(R.string.CONST_RestService) + "/json/Product/" + productID);
ResponseHandler<String> handler = new BasicResponseHandler();
result = httpclient.execute(request, handler);
jObject = new JSONObject(result);
What's going on?
Thanks
Dave
The JSON Data needs to be an evaluable JavaScript String - the " character needs to be escaped to \" (the character " as opposed to the String limitor "), and the \ in that expression needs to be escaped as well (because \ also is a special character). So it has been that string all along, it was just printed differently everytime.
Take this JavaScript for an example:
object = JSON.parse("{\"hello\":\"World\"}");
alert(object.hello);
The following is more of a guess than actual knowledge, because I do not know how exactly the classes you used behave, but I think that it's about right.
As you can see, the " characters need to be escaped to \", so your .NET JSON serializer does just that. Everything is fine, interpreting this as JS would work as expected.
Now what is probably going on is that your JSONObject constructor does not expect Strings to be already properly escaped, so it does that itself. To clarify: When you say "with one escape character", you probably mean something like this:
String workingJSONString = "{\"Hello\":\"World\"}"
right? The problem here is that Java has the same escaping rules as JavaScript - this is not what you get from your HTTPRequest, what you get is
String youGotThis = "{\\\"Hello\\\":\\\"World\\\"}"
Because there are literal backslashes in your String, and those need to be escaped as well. I am pretty certain that that is what is going on, and you'd probably either have to tell your .NET JSON serializer not to apply escape rules or find something that constructs a JSONObject from a properly escaped JSON string - or remove the unnecessary escapes yourself.
I hope this helped - but again, I am not fully certain so you should just check out if it actually behaves as I said.
Related
I have a stringified JSON object that I want to pass into my WebView as a string. If my JSON string is a simple one-level JSON like this:
JSONObject object = new JSONObject;
object.put("key1", "val1");
object.put("key2", "val2");
String myValue = object.toString();
And I run evaluateJavascript like this:
webView.evaluateJavascript("console.log('" + myValue + "')", null)
Then the console log I get is this:
{"key1": "val1", "key2", "val2"}
Which is correct.
But if my JSON has a sub JSON inside it, then the stringified version of that JSON should have escaped quotes in it for that inner JSON. So if I did this:
JSONObject object = new JSONObject();
object.put("key1", "val1");
JSONObject innerObject = new JSONObject();
innerObject.put("key3","val3");
object.put("key2", innerObject);
String myValue = object.toString();
And run the same evaluateJavascript statement above, I get the following console log
{"key1":"val1", "key2": "{"key3": "val3"}"}
Which is not what I am expecting! I'm expecting an output like this:
{"key1":"val1", "key2": "{\"key3\": \"val3\"}"}
The quotes of the inner JSON are supposed to be escaped. If they are not escaped, then trying to run a JSON.parse on it will result in a parse error.
I even used a debugger to inspect the run time value of myValue just before it is passed into evaluateJavascript and it looks the way it's supposed to:
"{"key1":"val1", "key2": "{\"key3\": \"val3\"}"}"
So why does running evaluateJavascript mysteriously strip away those explicit escape symbols?
NOTE:
The only way I could solve this was to run the following statement just before evaluateJavascript
myValue.replace("\\", "\\\\")
That is, replacing any escape characters (\) with 2 escape characters (\\). That way, the mysterious stripping will remove one escape character but leave the other one there which allows me to successfully JSON.parse it.
You can use URLEncode to encode the contents while using javascript interface.
URLEncoder.encode(contents, "UTF-8");
And then for getting back the actual contents in js you can use
decodeURIComponent(contents.replace(/\+/g, '%20'));
I'm currently deveolping an Android application that has Django framework as it's server side.
When i'm posting a data of a new user to my database i am POSTing a multipart request that has a user part inside.
The user for some reason is represented as a list but when i take it out of the request.data['user'] it's a str instance (Yea i dont know why...)
When i fetch that str i started working on it with json package.
I looked up on the internet (to many places..) how to convert a string in json format to a dictionary.
What i found is that when you use the json.loads command it doesn't give a dict back but a str instance :)
This is the code on my server side when i enter the create function of the ModelViewSet that handles the creation of the user.
userJson = request.data['user']
userJson = json.dumps(userJson)
userJson = json.loads(userJson)
What i tried to do is to make a string of my own in JSON format and that called the json.loads() command which gave me the dict object..
There seems to be a problem with processing the str from the http request of django rest framework for some reason or there's something else i am not seeing.
I tried the following links -
Converting JSON String to Dictionary Not List
http://docs.python-guide.org/en/latest/scenarios/json/
Didn't worked also..
Now, i tried accessing the str i got from json.loads() like a dictionary in this way.
id = userJson['id']
Now lets say maybe i passed a wrong json format to the loads function, it should have thrown an exception..
The code above (getting the id) raised an exception of 'String indices must be integer' - it doesn't convert it to dict! LOL xD
Good note worth mentioning - I'm trying to convert the json to a dictionary so i could access it like this - dictObject['id']
Well i would really appreciate every help!
Thanks :)
For some reason , when i did this commands-
userJson = request.data['user']
userJson = json.loads(userJson)
userJson = json.loads(userJson)
What i got to have inside the userJson after the second json.loads(userJson) I got the actual dict object to the userJson member.
Appearently it is a bug.
21 January - another update, I truly was doing double Json encoding on the Android application so that was the reason for double json. loads()
I'm sending string below from Android to web service using volley request
params.put("data", objData.toString());
objData.toString() -->
{"report_time":1413876429,"device_id":"13d404d1b3a38ffc","ads_info":"[{\"play_count\":\"26\",\"ad_id\":\"21\"},{\"play_count\":\"58\",\"ad_id\":\"37\"},{\"play_count\":\"14\",\"ad_id\":\"40\"}]"}
Server not accepting it due the \"
How to remove \ keeping the json correct ""
You are not using the web service correctly.
Possibly the service expects to see a JSON array instead of a string containing JSON. Assuming params is a JSONObject and objData is a JSONArray, use params.put("data", objData) instead of the toString() version you have now.
Escaping the double quotes with backslashes is the only way to do this in java.
One other option would be to put the String into some kind of text file that you would then read at runtime.
I have a client / server app written using Android and I'm using the standard org.json package classes bundled with android to do the parsing and creating.
I've been getting weird characters appearing on the server side right in the middle of the json strings generated for example (not the full one, because its big):
{!lo":"es_MX","id":2791884,"os":"8"}
As you can see the (!) exclamation mark appears randomly instead of a double quote. I also get other random characters appearing mid string. It's very bizarre.
Here is the code which creates the JSON object...
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", someValue);
Here is the code which sends..
HttpPost type = new HttpPost(<server url here>);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("v", jsonObject.toString()));
type.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
httpClient.execute(type); // This is a DefaultHttpClient
I say random, but the exclamation mark in this exact position is consistent in many errors, but not every-time. About 5 messages that get this error, among tens of thousands per day. And usually not the contents of the values inserted into the json, but the characters (such as the quote character above) that define the structure of the message, which suggests to me that this isn't a character set issue.
Has anyone come across this?
it seems you are composing string in other format, and on receiving text decode in another format
like iso to utf.
It looks like your sender is not properly setting the character set. Spanish will have symbols not present in regular ASCII or most Windows encodings, you need to use UTF-8:
Content-Type: text/html; charset=utf-8
Without knowing which HTTP exchange you're using (read more), it is not possible to give you an exact code snippet to fix the problem - but that should be easy enough to figure out.
You give not enough information. Radical method to fix your problem is just replace all (!) characters to (").
string.replaceAll("!", "\"");
I guess it is server side issue.
I had also simmilar problem. Let me write much more to describe my environment. My server was returning data in json format. But my problem was connected with special chars like ąść. YOu should know, json_encode() will return from server in this case string text as a null.
I know, it sucks! So I added mysql_query('SET CHARACTER SET utf8'); before my selction for items from database. This allowed me to take strings from server with special diacritics letters.
Now on the app site, I was taking data from server by GET method. First I was storing result data into InputStream. Then I was packing it into InputStreamReader and byte by byte I was appending it into stringBuilder. That's ready appended text was converting by toString() ready string. Then I was putting it to new JsonArray(readyString). However I discovered some parts of text for json had weird chars.. Especially in that places where were special letters like żóć. For example "description":"aaa" was throwing "descriptionPffa":"aa"null:`.
I decided to try another way for converting result from data. In places where I was converting data from server I used method below. At the end, wgen I got byteArrayOutputStream object I changed it to new String(byteArray) and then somehow it worked with new JsonArray(new String(byteArray))!
public class Streams {
public static byte[] getBytes(InputStream is) {
int len;
int size = 1024;
byte[] buf = new byte[0];
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
buf = new byte[size];
while ((len = is.read(buf, 0, size)) != -1)
bos.write(buf, 0, len);
buf = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return buf;
}
}
Print the json on the client (using Log.d or similar) and see if it contains weird characters before sending it to the server.
If you check my previous questions, you will see that they are all in some way related to "\" or "/" for Android and why my implementations of code wasn't working when other people's versions were.
I now know why mine wasn't working.
I am developing for a live client who has access to a content management system, from which I am getting the data. Other than the general checks, they can post anything they want to the site.
They are posting sizes in inches; e.g. 5-1/2
It is this, and this alone, which is screwing up my Restful json.
For example, 1 eigth has become
1\\\/8
Currently, I am doing a string rewrite at the WCF point to catch these 'fractions' and turn them into decimal just so I can continue development. But I can't code for every eventuality and Android/Eclipse fails at JSONArray json=new JSONArray(result);
Would appreciate any input on this.
Dave
On reflection, and further investigation, it isn't the escaped fractions causing the problem.
It is something more fundamental.
Will close the question.
I have searched high and wide for an answer to this, and have finally found it.
I will share for anyone else experiencing the same issue:
It is the WCF Rest service.
Learning WCF and Android at the same time led me to believe that the response from WCF should be a String serialized in the Json format.
To do this, a .Net object, array or whatever would go through DataContractJsonSerializer before being returned as a String to Android for further parsing.
Something like this:
Dim stream1 As MemoryStream = New MemoryStream
Dim ser As DataContractJsonSerializer = New DataContractJsonSerializer(GetType(myType))
ser.WriteObject(stream1, myThing)
Dim _json As String = Encoding.UTF8.GetString(stream1.ToArray())
stream1.Close()
return _json
Wrong.
Keep your object, array or whatever and return that instead; WCF will take care of the proper escaping for you.
For example (this is VB);
IService:
<OperationContract()> _
<WebGet(BodyStyle:=WebMessageBodyStyle.WrappedRequest, RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json, UriTemplate:="/MyKit/{AccountID}")> _
Function GetKit(ByVal AccountID As String) As MyKit
Service:
Public Function GetKit(ByVal AccountID As String) As MyKit Implements IService1.GetKit
Dim allKit As New MyKit() //Your object
objDal.CommandText = 'run some sql here - or whatever
Using dr As SqlDataReader = "blah"
//populate your object
End Using
Return allKit //return the object, not the string representation of it
End Function
Using DataContractJsonSerializer for sending as Json to Android from WCF effectively 'pre-escapes' the data. When it gets to Android, the Json parser is unable to handle it, because it also escapes the data.