LINQ on JArray always returning null - json

I'm trying to parse some Json in Xamarin.Forms
I'm pretty new to Xamarin, though not to .net
Here's my simple dimple code
var htc = new HttpClient();
var rsp = await htc.GetStringAsync("myurl.com");
JArray lists = JArray.Parse(rsp);
var c = lists.Count();
var l = lists.ToList();
var w=lists.Where(x => true);
Even though c returns the correct count of items in the list, l & w are both null
How come? and how do I fix it?
Thanks!
PS. What I'm really trying to do is bind a ListView to a JArray, but it seems impossible directly,(Text={Binding MyPropertyName} crashes the app). so I'm trying to run a Select on the JArray to convert to a KeyValuePair. If you have any ideas to bind directly, that would be best!
UPDATE
The issue seems even odder
I tried this
var kvlist = new List<KeyValuePair<string, string>>();
foreach (JObject ll in lists)
{
kvlist.Add(new KeyValuePair<string, string>(ll["Name"].ToString(), ll["Name"].ToString()));
}
Here at least the iteration works nicely, but the kvlist is null the entire time. Trying to evaluate the kvlist variable, I get:
Unable to cast object of type 'System.RuntimeType' to type
'Mono.Debugger.Soft.TypeMirror'.
What can the matter be?
Thanks again!

You should not directly call .ToList on object type of JArray rather you should Select List of type you need. For ex.
var l = lists.Select(c => new MyList
{
Item1 = c.Value<int>("ItemName1"),
Item2 = c.Value<string>("ItemName2")
}).ToList(); //Replce MyList with your class name
On the second case where w is null, after getting list l you need to specify attribute, based of what you are using where clause. For ex.
var w=l.Where(x =>x.isAdmin==true); //l is list you selected above
Hope it help you.

Solution:
You can use code below to convert a JArray to a list<T>:
List<T> t =lists.ToObject<List<T>>();
Refer: https://www.newtonsoft.com/json/help/html/ToObjectType.htm
You could also use JsonConvert.DeserializeObject to convert it directly into the desired type. You have to define a jsonModel class with the same structure of your json fisrtly.
List<jsonModel> modelList = JsonConvert.DeserializeObject<List<jsonModel>>(jsonStr);
Refer :https://www.newtonsoft.com/json/help/html/SerializingCollections.htm

The documentation seems to indicate that JArray has properties for .Count, but no overload method because it does not implement IEnumerable, however as alluded to in the comments, it does implement the JToken type (which JArray is a collection of) and implements IEnumerable.
See the following documentation for JToken: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JToken.htm
and JArray respectively:
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JArray.htm
The preferred mechanism is to create a strong type and then run .ToObject();
You can access JArray.ChildrenTokens which may help

Related

convert a string to JSON Object with same name (Need this for some sort of dynamic code in js)

var ObjName = "Person";
//If I assign "Institute" then I need Institute JSON object
//I have a global Person JSON with many attributes.
var thisObj = ObjName.toObject(); //need something of this kind
//I know eval can be used, but just checking any other better way to do this.
Please advise if there is better way to convert String to Object of its name in nodejs, sails js
It is not technically possible in ES5 JavaScript to do exactly what you want without the use of eval. As you have eluded to, it would not be a good idea to use eval in the this situation (or pretty much all). An alternative such as that which David suggested is probably a good go-to for now.
//Set the variable
var ObjName = "person";
//define the initial object
var thisObj = {};
//Add some objects to it.
thisObj[ObjName] = {'things':'stuff'};
//Or, because we know the object name is 'person', attach stuff directly to it.
thisObj.person = 'test';
//Or, (again) if we need to reuse the variable as string later on
thisObj['person'] = 'test';

Generate a JSON object form a the value of another JSON in WP8

I am working on a WP8 app. In this I need to connect to web services whose results will be some JSON. I was trying to extract some data from the result that the web service provide. I was able to extract from the initial JSON response. But I need to get some data from the value of one such key . SO I tried to generate another Json object from it. But I m stuck. please help.Please find my example code below(I am using Newtonsoft.JSon).
private void messages_buttons_Click(object sender, RoutedEventArgs e)
{
var str = "{'status': '0', 'result': '%7B%22campaign_id%22%3A%221%22%2C%22tfn%22%3A%2218773374136%22%2C%22campaign_code%22%3A%22PJC%22%2C%22ad_id%22%3A%221%22%2C%22qr_url%22%3A%22http%3A%5C%2F%5C%2F1d1.us%5C%2FPJC%5C%2F%22%2C%22campaign_name%22%3A%22PJ+Test+Campaign%22%2C%22is_active%22%3A%221%22%2C%22expire_on%22%3A%222021-05-05+00%3A00%3A00%22%2C%22start_on%22%3A%222021-05-05+00%3A00%3A00%22%2C%22alias%22%3A%22%22%2C%22icon_image_url%22%3A%22products%5C%2Fpjc%5C%2Fpjc3.jpg%22%2C%22fb_page_url%22%3A%22https%3A%5C%2F%5C%2Fwww.facebook.com%5C%2FJackLaLannePowerJuicerssfb%22%2C%22video_url%22%3A%22http%3A%5C%2F%5C%2Fyoutube.com%5C%2Fembed%5C%2FyZPedpRA9r0%3Fshowinfo%3D0%26autoplay%3D1%26loop%3D1%26playlist%3DyZPedpRA9r0%22%2C%22url%22%3A%22https%3A%5C%2F%5C%2Fwww.facebook.com'}";
JObject ne = JObject.Parse(str);
var x= (ne.GetValue("result")).ToString();
var z = x.Replace("%", "");
JObject newest = JObject.Parse(z);
var y = newest.GetValue("campaign_id");
MessageBox.Show(y.ToString());
}
I get an exception at "JObject newest = JObject.Parse(z);" with the message
Unexpected character encountered while parsing number: m. Path '', line 1, position 6.
Am I doing it entirely wrong?
On a general note: can I convert a value from one Json to a another JSOn Itself? i.e if the value of one json key is a string with some key value pairs, can i make a json object on that string?
You can't actually just remove the % chars to get a valid value. You need to decode the string.
If you use this:
HttpUtility.UrlDecode(x);
You'll find your "result" is actually invalid JSON:
{"campaign_id":"1","tfn":"18773374136","campaign_code":"PJC","ad_id":"1","qr_url":"http://1d1.us/PJC/","campaign_name":"PJ
Test Campaign","is_active":"1","expire_on":"2021-05-05
00:00:00","start_on":"2021-05-05
00:00:00","alias":"","icon_image_url":"products/pjc/pjc3.jpg","fb_page_url":"https://www.facebook.com/JackLaLannePowerJuicerssfb","video_url":"http://youtube.com/embed/yZPedpRA9r0?showinfo=0&autoplay=1&loop=1&playlist=yZPedpRA9r0","url":"https://www.facebook.com
So hacking the value to make it valid JSON might work for you, by adding the missing "} at the end should turn your value in to valid JSON and allow you to parse it.
JObject newest = JObject.Parse(x + "\"}");
var y = newest.GetValue("campaign_id");
It doesn't appear that z is a valid json object at this point. It is only the value of result. Try something like JObject.Parse("'result':" + z);

Parse Nested JSON with MiniJSON (Unity3D)

i'm very newbie with JSON so i'm having problems with nested JSON's.
I was searching two days without any luck, i saw a lot of examples of how to deserialize a nested JSON but my efforts failed so at last chance i'm here.
The thing i want to know is how i deserialize nested class with MiniJson, the JSONString is a facebook one, but i want to know the method for do it.
Here is an example of the JSONString i'm trying to deserialize.
{"data":
[{"user":{"name":"xxxxxxxxx1","id":"xxxxxxxxxx2"},"score":7,
"application":
{"name":"APPNAME","namespace":"APPNAMESPACE","id":"xxxxxxxxxx3"}}]}
Thanks in advance...
I tried with a lot of things this one is the last attempt i did, not a lot good but i was trying like a crazy to do it:
object dataObject;
object scoreObject;
var dict = Json.Deserialize(response.Text) as Dictionary<string,object>;
Debug.Log(response.Text);
var scores = new List<object>();
if(dict.TryGetValue ("data", out scoreObject)) {
Debug.Log("Hi");
scores = (string)(((Dictionary<string, object>)scoreObject) ["score"]);
if(scores.Count > 0) {
var scoreDict = ((Dictionary<string,object>)(scores[0]));
var score = new Dictionary<string, string>();
score["score"] = (string)scoreDict["score"];
Debug.Log((string)scoreDict["score"]);
}
}
PD: Sorry if my question is very noob or if i have a lot of negatives but it's really my last chance to understand something, thanks again.
Your problem lies in the fact that data contains an array and not an object, you need to get the first element of the data array and then get the value of score.
Something like this:
var dict = Json.Deserialize(response.Text) as Dictionary<string,object>;
List<object> scores = dict["data"] as List<object>;
Dictionary<string,object> scoreData = scores[0] as Dictionary<string,object>;
object score = scoreData["score"];

How to JSON serialize math vector type in F#?

I'm trying to serialize "vector" (Microsoft.FSharp.Math) type. And I get that error:
Exception Details: System.Runtime.Serialization.SerializationException: Type 'Microsoft.FSharp.Math.Instances+FloatNumerics#115' with data contract name 'Instances.FloatNumerics_x0040_115:http://schemas.datacontract.org/2004/07/Microsoft.FSharp.Math' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
I have tried to put KnownType attribute and some other stuff, but nothing helps!
Could someone know the answer?
This is the code I use:
// [< KnownType( typeof<vector> ) >]
type MyType = vector
let public writeTest =
let aaa = vector [1.1;2.2]
let serializer = new DataContractJsonSerializer( typeof<MyType> )
let writer = new StreamWriter( #"c:\test.txt" )
serializer.WriteObject(writer.BaseStream, aaa)
writer.Close()
I think that F# vector type doesn't provide all the necessary support for JSON serialization (and is quite a complex type internally). Perhaps the best thing to do in your case would be to convert it to an array and serialize the array (which will also definitely generate shorter and more efficient JSON).
The conversion is quite straightforward:
let aaa = vector [1.1;2.2]
let arr = Array.ofSeq aaa // Convert vector to array
// BTW: The 'use' keyword behaves like 'using' in C#
use writer = new StreamWriter( #"c:\test.txt" )
let serializer = new DataContractJsonSerializer()
serializer.WriteObject(writer.BaseStream, aaa)
To convert the array back to vector, you can use Vector.ofSeq (which is a counterpart to Array.ofSeq used in the example above).
You can also use:
let v = vector [1.;3.];
let vArr = v.InternalValues
to get the internal array of the vector. In this way, you don't need to create a temporary array.
Types, RowVector, Matrix also has this method to get the internal arrays.

Concatenate JsonRepresentation

How can I concatenate multiple JsonRepresentation Object into one, without building my own string parser?
Say I have two JsonRepresentation objects
obj1 = {"name":"obj1"};
obj2 = {"name":"obj2"};
I would like to get the result concatenation as:
{
{"name":"obj1"},
{"name":"obj2"}
}
Reading the JsonRepresentation, there is no easy way to do this except by doing some string manipulation. Am I right?
Thanks
If you're referring to this JsonRepresentation class, and you want to merge the 2 objects into an array, then you should be able to do it as follows:
JSONObject jsonObj1 = obj1.toJsonObject();
JSONObject jsonObj2 = obj2.toJsonObject();
JSONArray jsonArray = new JSONArray().append(jsonObj1).append(jsonObj2);
JsonRepresentation jsonConcat = new JsonRepresentation(jsonArray);
Note: I haven't actually used the library, but if it behaves per the API, this should be pretty straightforward.