NewtonSoft Json.NET and Single Element Arrays - c#

I have some JSon that I am converting to an object using the ToObject method.
A part of this Json has a repeated element which is correctly represented as an array in the Json text. When I convert this it correctly is mapped to the C# object
public IList<FooData> Foo { get; set; }
But when I only have 1 element I get an error saying that the Json that I am trying to Parse into an object is not an array because it does not have [] around it.
Does Json.NET support single element arrays?

But when I only have 1 element I get an error saying that the Json
that I am trying to Parse into an object is not an array because it
does not have [] around it.
If a JSON text has no [] around, then it's not a single-element array: actually it's an object (for example: { "text": "hello world" }).
Try using JsonConvert.DeserializeObject method:
jsonText = jsonText.Trim();
// If your JSON string starts with [, it's an array...
if(jsonText.StartsWith("["))
{
var array = JsonConvert.DeserializeObject<IEnumerable<string>>(jsonText);
}
else // Otherwise, it's an object...
{
var someObject = JsonConvert.DeserializeObject<YourClass>(jsonText);
}
It can also happen that JSON text contains a literal value like 1 or "hello world"... but I believe that these are very edge cases...
For the above edge cases just deserialize them with JsonConvert.DeserializeObject<string>(jsonText) for example (replace string with int or whatever...).

Make sure you are enclosing your JSON single item array is still specified as an array using array notation []

Related

How does a wrapper work for JsonUtility

So I've been looking to convert my Json array into an array of objects in Unity. I've found my solution from a 2 yeard old thread without explanation but I'm curious as to how it actually works.
If I use Visual Studio to look for the definition of FromJson it shows me this
public static T FromJson<T>(string json);
As I understand is that FromJson asks for an object to be filled, I give the class MyWrapper but besides telling MyWrapper that he contains a list of Question I never ask it to create a new item in the list. So how does it actually fill the list?
C#
MyWrapper wrappedQuestions = JsonUtility.FromJson<MyWrapper>(jsonString);
[Serializable]
public class MyWrapper
{
public List<Question> questions;
}
[Serializable]
public class Question
{
public int questionType;
public string questionString;
public int questionAnswer;
}
Json
{
"questions": [
{
"questionType": 1,
"questionString": "4^2",
"questionAnswer": 16
},
{
"questionType": 2,
"questionString": "√(25)",
"questionAnswer": 5
}
]
}
I'm still a beginner programmer so I hope I'am able to ask such questions here.
If you wonder why you need a wrapper for that, that's simply because Unity engineers did not add direct support for primitive types or arrays. It's just how they programmed it. Most Json API are not like this.
So how does it actually fill the list?
Reflection.
1.It reads the json you passed to it. It detects the questions variable in the json. It detects that the questions variable is an array due to the format such as [] and the commas that separates each item.
2.It finds the type of that questions variable which is Question or List of Question.
3.It uses Activator.CreateInstance to create new instance of Question, read each value from each variable in the json and then fill them up with reflection with that new instance it created.
4. It returns the new instance that is filled.
If you read and understand how to do basic stuff with reflection in C#, you may be able to make your own simple Json parser with the Queue class.
Finally, you can use the JsonHelper wrapper from this answer to serialize/de-serialize arrays easily without having to make a wrapper for each class.
As JSON stands for Javascript Object Notation, JSON objects (strings) follow a pattern. For any string to parsed and converted to the object, it has to be a valid JSON. It has certain rules/syntax,
for example
[ ] is for array/list,
{ } is for objects
and every object can contain key-value pairs (separated by colon :) to represent variables along with their values
{ "Key" : "Value" }
Now JSON parser is aware of these rules so it can check if any string is valid JSON.
What does it need to know to convert a JSON into a class object?
The class type you provide here :
JsonUtility.FromJson<MyWrapper>(jsonString);
is MyWrapper.
It should have the same structure as your jsonString.
Let's break down your jsonString to map it with the class structure:
This represents a MyWrapper object. which contains only one property called questions, which is an empty list.
{
"questions": [ ]
}
if questions have any element in it, it would be of type Question we can write it as following in JSON:
{
"questionType": 1, // int value
"questionString": "4^2", // string value
"questionAnswer": 16 // int value
}
now if questions have more than one elements they would be separated by a comma:
"questions": [
{
"questionType": 1,
"questionString": "4^2",
"questionAnswer": 16
},
{
"questionType": 2,
"questionString": "√(25)",
"questionAnswer": 4
},
...
]
JSON parser is aware of all these rules so by looking at class structure it can parse the string and create an object of the stated class provided that JSON is valid and class structure matches with JSON structure.
That's all I could say about this, hope you got the basic understanding.

How can I parse a string representation of an array of array of doubles?

I'm passing a JSON object in C#. The original object is an array of arrays of doubles, e.g.
var arrayObject = [[1.2,3,1,0],[2.3,1,0,9],[3,6.7,9,1]]
To pass between JavaScript and C# this has been converted to a JSON representation of an array of arrays:
string json = "[[1.2,3,1,0],[2.3,1,0,9],[3,6.7,9,1]]"
How can I parse this? I want to do something like JavaScriptSerializer().Deserialize<List<myObject>>(json), but this gives me an error that "Type 'myObject' is not supported for deserialization of an array."
There's not much structure here in terms of a JSON object...and all I really need to do is parse this out into a set of arrays.
I've read a little about Json.NET, but I don't want to add unnecessary class libraries. Is there a simple way to parse this string?
First, deserialize it into something the serializer does understand - a double[][] - then you can convert it however you want:
string json = "[[1.2,3,1,0],[2.3,1,0,9],[3,6.7,9,1]]";
double[][] arrayOfArrays = new JavaScriptSerializer().Deserialize<double[][]>(json);
Assuming your myObject class looks something like:
class myObject {
public double[] Arr { get;set; }
}
Then you could use LINQ to convert it to what you're looking for:
List<myObject> list = arrayOfArrays.Select(x => new myObject { Arr = x }).ToList();

How to pass values to string array in post method using Fiddler?

When I'm passing the values in Fiddler like {"rajehs","ramesh","ramsgkfhh"}, I'm getting all the values in [0] location. I've also tried by using = {"rajehs","ramesh","ramsgkfhh"}.
I declared the method like :
public void Post([FromBody]string[] value)
{
}
You are passing a JSON object in our body, instead of an array. Use [] to pass a JSON array:
["rajehs","ramesh","ramsgkfhh"]

Decimal precision of zero when serializing doubles to JSON

Consider the following JSON object:
{
"value": 0
}
Now suppose I'm mapping this to a .NET type Foo:
class Foo
{
public double Value { get; set; }
}
The type of Foo.Value is double, because Value isn't always an integer value.
Using JSON.NET, this works beautifully:
Foo deserialized = JsonConvert.DeserializeObject<Foo>(json);
However, observe what happens when I try to convert the object back to its JSON representation:
string serialized = JsonConvert.SerializeObject(deserialized, Formatting.Indented);
Output:
{
"Value": 0.0
}
Notice the trailing zero? How do I get rid of it?
EDIT
I suspect that the answer will be write your own converter. If it is, then that's fine and I guess I'll accept that as the answer. I'm just wondering if perhaps there exists an attribute that I don't know of that lets you specify the output format (or similar).
It appears that this is a hard-coded behavior of the library:
https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/JsonConvert.cs#L300
If you want to alter the behavior you'll need to edit the library and recompile from source (or choose another JSON library)

C#, JSON Parsing, dynamic variable. How to check type?

I'm parsing JSON texts. Sometimes I get Array and sometimes Object types in the text. I tried to check the type as follows:
dynamic obj = JsonConvert.DeserializeObject(text); //json text
if (obj is Array)
{
Console.WriteLine("ARRAY!");
}
else if (obj is Object)
{
Console.WriteLine("OBJECT!");
}
I checked the types while debugging. obj had Type property as Object when parsing objects and Array when parsing arrays. However the console output was OBJECT! for both situations. Obviously I'm checking the type in a wrong manner. What is the correct way to check the type?
EDIT
JSON contents:
[ {"ticket":"asd", ...}, {..} ] or { "ASD":{...}, "SDF":{...} }
In both situations I get the output as OBJECT!.
EDIT#2
I changed the typechecking order as #Houssem suggested. Still the same output. Therefore I changed the OP as well. My code is like this right now, and I still get the same result.
Try this, since the JSON.NET return an object of type JToken
if (((JToken)obj).Type == JTokenType.Array)
{
Console.WriteLine("ARRAY!");
}
else if (((JToken)obj).Type == JTokenType.Object)
{
Console.WriteLine("OBJECT!");
}

Categories

Resources