I am trying to convert the NSDictionary into Json using NSJsonSerialization.Serialize. But i am not getting expected output
Code in Xamarin.iOS
var dictionary = new NSDictionary(
new NSString("userName"), new NSString("450012"),
new NSString("password"), new NSString("Abc134"),
new NSString("companyId"), new NSString("CM1")
);
request.Body = NSJsonSerialization.Serialize(dictionary, 0, out error);
the problem is that value of dictionary variable is showing
{{password":Abc134,companyId:CM1,userName:450012}}
instead of
{password:Abc134,companyId:CM1,userName:450012}
it is adding one curly braces at the front and back
is there any way to generate proper json string for user input values
There's nothing wrong with your json. If you print it in the console you will see that the value being printed is the value you expect.
{"password":"Abc134","companyId":"CM1","userName":"450012"}
Give it a try with:
Console.WriteLine($"{json}");
If you really, really want to get rid of of that "extra" curly braces just convert the result into string.
var jsonString = json.ToString();
The above should do the work.
I would just suggest you changing your method to this:
var json2 = NSJsonSerialization.Serialize(dictionary, NSJsonWritingOptions.PrettyPrinted, out error);
Using the PrettyPrinted option.
Hope this helps.-
Yes, you can try to create a custom object to serialize. Create a simple plain object to hold the data you want.
User user = new User() {
UserName = "JohnDoe",
Password = "xxx",
CompanyId = 01
};
request.Body = NSJsonSerialization.Serialize(user, 0, out error);
Then serialize it and you will see the proper json well formed.
Related
I am trying to console.log("ctx : "+ ctx.request.body);
To view what is in the JSON that received when tried it shows ctx : [object Object].
But if I console.log("ctx : ", ctx.request.body); like this it prints the JSON correctly
without + in console.log().
I want to know what is the reason behind this logic
When you use someString + someObject, when the result is a new string. The object must be converted to a string first before the new string can be created.
Whenever an object is cast to a string in Javascript, the result is [object Object].
To see this behavior you can also.
const obj = {};
const str = obj.toString(); // convert to string
console.log(str);
If you want to have a formatted json output you also can do the following:
console.log("ctx:");
console.log(JSON.stringify(ctx.request.body, null, 2);
We have below JSON response which has dynamically getting one of the JSONobject which has other objects inside. Tried some of the solutions provided here, but unable to get the values, every time getting 'null'.
{
"Result": {
"12987654": {//this value 1298.. is dynamically getting generated at every response.
"Tests1": {
"test1": -0.85,
"test2": 0.016,
"tests3": "FAIL"
},
"Tests2": {
"test21": "PASS",
"test22": "PASS",
"test23": "FAIL"
}
}
}
}
Now Trying to get value of inside this dynamically (1298..) generating object, like Tests2.teset21.
If tried as
JSONPath js.get("Results.1298.Tests1.test1")//able to get the value. however here 1298 is hardcoded and this value changes in the next run.
If tried as below, getting value as null.
import com.google.gson.JsonObject;
JsonObject jsonObjectResponse = (JsonObject) new JsonParser().parse(responseInString);
JsonObject Result = jsonObjectResponse.get("loanResult").getAsJsonObject();
SysOut(Result)//gives null
OR, trying below also gives null
JsonElement jelement = new JsonParser().parse(responseInString);
JsonObject ResultObj = jelement.getAsJsonObject();
System.out.println("ResultObj value is: " + loanResultObj.get("tests21"));
Please guide how to get value inside of dynamically generating Jsonobject.
Finally after many attempts, could understand using Gson to get the value. For my issue, the id which dynamic goes from Request. With below code could solve issue:
Gson gsonResp = new Gson();
String responseInString = response.asString();
JsonObject jsonObjectNewResponse = gsonResp.fromJson(responseInString, JsonObject.class);
String test12 = jsonObjectNewResponse.getAsJsonObject("Result").getAsJsonObject(<dynamicID which is been extracted from Req in the form of String>). getAsJsonObject("test1").get("test12").getAsString();
I am building a Chrome extension which should write new rows into a Google Spreadsheet. I manage to read the sheet content but am not able to write an additional row. Currently my error is "400 (Bad Request)". Any idea what I am doing wrong here?
I have gone through the Google Sheets API documentation and other posted questions here but was not able to find any solution.
Here is the code which I use to GET the sheet content (this works):
function loadSpreadsheet(token) {
var y = new XMLHttpRequest();
y.open('GET', 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/values?access_token=' + token);
y.onload = function() {
console.log(y.response);
};
y.send();
}
And this is the code I try to POST a new row (gives me "400 - Bad Request"):
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',//'--END_OF_PART\r\n',
'<gsx:name>',foo,'</gsx:name>',//'--END_OF_PART\r\n',
'</entry>'].join('');
return atom;
};
var params = {
'body': constructAtomXML("foo")
};
url = 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
Note: spreadsheet_id is a placeholder for my actual sheet ID.
Follow the protocol and to make it work.
Assume spreadsheet ID is '1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8'
First use the spreadsheet ID to retrieve list of worksheets:
GET https://spreadsheets.google.com/feeds/worksheets/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/private/full?alt=json
There you can read list of worksheets and their IDs. Let use the first worksheet from the example. You'll find its id in feed > entry[0] > link array. Look for "rel" equal 'http://schemas.google.com/spreadsheets/2006#listfeed'.
In my example the URL for this worksheet is (Worksheet URL): https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full
Now, to read its content use:
GET [Worksheet URL]?alt=json
Besides list-row feed, you'll also find a "post" URL which should be used to alter spreadsheet using list-row feed. It's the one where "rel" equals "http://schemas.google.com/g/2005#post" under feed > link.
It happens that it is the same URL as for GET request. In my case: https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full. Just be sure to not append alt=json.
Now, to insert a new row using list-row feed you need to send POST with payload which is specified in docs. You need to send a column name prefixed with "gsx:" as a tag name. However it may not be the same as the column name in the spreadsheet. You need to remove any white-spaces, make it all lowercase and without any national characters. So to make your example work you need to replace <gsx:Name> with <gsx:name>.
Before the change you probably had the following payload message:
Blank rows cannot be written; use delete instead.
It's because the API didn't understand what the "Name" is and it just dropped this part of entry from the request. Without it there were no more items and the row was blank.
Alternatively you can read column names from the GET response. Keys from objects in feed > entry array that begins with gsk$ are columns definitions (everything after $ sign is a column name).
=================================================================
EDIT
To answer a question from the comments.
I've changed two things from your example:
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',
'<gsx:name>',foo,'</gsx:name>',
'</entry>'].join('');
return atom;
};
/*
var params = {
'body': constructAtomXML("foo")
};
*/
var params = constructAtomXML("foo");
url = 'https://spreadsheets.google.com/feeds/list/'+spredsheetId+'/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
1) <gsx:Name> to <gsx:name>. Without it you'll receive an error.
2) params object should be a String! Not an object with some 'body' key. You just need to pass a value you want to send to the server.
I am running this script for getting all form fields of a indd file.
var _ALL_FIELDS = "";
var allFields = myDocument.formFields;
for(var i=0;i<allFields.length;i++){
var tf = allFields[i];
alert(tf.id);
alert(tf.label);
alert(tf.name);
alert(_ALL_FIELDS = _ALL_FIELDS +\",\"+ tf.name);
}
What i have done is, created a soap-java based client and calling the runscript method.
Now i am able to get these fields but how to send these fields back to the client i.e. how to write this in response and then at client side how to read it from response.
Code for calling runscript method is:-
Service inDesignService = new ServiceLocator();
ServicePortType inDesignServer = inDesignService.getService(new URL(parsedArgs.getHost()));
IntHolder errorNumber = new IntHolder(0);
StringHolder errorString = new StringHolder();
DataHolder results = new DataHolder();
inDesignServer.runScript(runScriptParams, errorNumber, errorString, results);
Also I have found in docs that runScript method returns RunScriptResponse but in my case it's returning void.
http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/indesign/sdk/cs6/server/ids-solutions.pdf
It looks like you want to return an array of formField names. You could take advantage of the everyItem() collection interface method in your javascript:
var result = myDocument.formFields.everyItem().name;
result;
The javascript will return the last value in the called script, so just to make it completely obvious, the last line is just the value to be returned.
On the Java side, the runScript method is passing the results variable as the 4th parameter, and that's where you'll find your response. So, after your code snippet, you might have something like this:
List<String> formFieldNames = new ArrayList<String>();
if (results.value.getData() != null) {
Data[] resultsArray = (Data[]) results.value.getData();
for (int i = 0; i < resultsArray.length; i++) {
formFieldNames.add(resultsArray[i].getData().toString());
}
}
Using the below formatter, I convert properties in my C# classes that are naturally beginning with uppercase to lowercase. However, when I turn around and post those back to POST and PUT, they are coming back up in lowercase first letter and of course that does not map back to the C# class.
What is best way to handle data going back to POST and PUT without having to parse the javascript and do the conversions by hand?
config.Formatters[index] =
new JsonMediaTypeFormatter
{
SerializerSettings =
new JsonSerializerSettings
{
ContractResolver =
new CamelCasePropertyNamesContractResolver
(),
DateTimeZoneHandling = DateTimeZoneHandling.Local,
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore
}
};
Instead of creating a new JsonMediaTypeFormatter you can simply modify the existing JSON formatter as follows:
httpConfiguration.Formatters.JsonFormatter.SerializerSettings =
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
DateTimeZoneHandling = DateTimeZoneHandling.Local,
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore
};
Maybe that will work...