How to read JSON data? - c#

Is this json data format?
string json = {"answer":"Line 1","mark": 1},{"answer":"Line 3","mark": 1}
I try below code but it only working with one param. ex: {"answer":"Line 1","mark": 1}. I try split json string but it isn't best way.
JObject jObject = JObject.Parse(json );
string asw = jObject["answer"].ToString();
int mark = (int)jObject["mark"];
txtAnswer.Text = asw + "////" + mark + "\n";

This is a very basic JSON question which any number of tutorials could've answered for you.
Is it valid JSON ? No, and JSONLint could've told you that.
How do you read it in ?
First, wrap your JSON in square brackets so it's valid.
Then, define a class to store the records in:
public class Something
{
public string answer { get; set; }
public string mark { get; set; }
}
And finally, use JSON.Net to convert your string into a list of these records.
string json = "[{\"answer\":\"Line 1\",\"mark\": 1},{\"answer\":\"Line 3\",\"mark\": 1}]";
List<Something> records = JsonConvert.DeserializeObject<List<Something>>(json); // JSON.Net
foreach (Something record in records)
{
System.Diagnostics.Trace.WriteLine(string.Format("Answer: {0}, Mark: {1}", record.answer, record.mark));
}
Easy as that.

Is this json data format?
string json = {"answer":"Line 1","mark": 1},{"answer":"Line 3","mark": 1}
Nope, what you've got there doesn't look like valid C# or JSON. Try putting it inside a JSON array, then inside a proper string:
string json = "[{\"answer\":\"Line 1\",\"mark\": 1},{\"answer\":\"Line 3\",\"mark\": 1}]";
(Hope I've got all the escaping right there.)
That's the C# escaped equivalent of the following JSON:
[{"answer":"Line 1","mark": 1}, {"answer":"Line 3","mark": 1}]
Then read up on JObject.Parse()for more info.

Yes it is json format. But There are multiple objects. You are not looping through it. One way could be
dynamic dynJson = JsonConvert.DeserializeObject(json);
foreach (var item in dynJson)
{
Console.WriteLine("{0} {1}\n", item.answer, item.mark);
}

Related

Split string with multiple json strings [duplicate]

This question already has answers here:
What is the correct way to use JSON.NET to parse stream of JSON objects?
(1 answer)
Best ways to split a string with matching curly braces
(2 answers)
Closed 5 years ago.
I am trying to split a c# string that has multiple json strings in it
Example:
{"id":0,"username":"test"}{"id":8,"username":"testuser"}
How can I loop through each json string in its own 'foreach' loop
hi you can do some trikk on invalid json...
string myinvalidJson = "{\"id\":0,\"username\":\"test\"}{\"id\":8,\"username\":\"testuser\"}";
foreach(var item in myinvalidJson.Replace("}{", "}|{").Split('|')) {
...
}
or create valid json and deserialize with newtonsoft
string myinvalidJson = "{\"id\":0,\"username\":\"test\"}{\"id\":8,\"username\":\"testuser\"}";
var validJson = "[" + myinvalidJson.Replace("}{", "},{") + "]";
You may Deserialize it into array of structure type using Newtonsoft.Json
to do this you need to have a string matching an array of JSONs like below:
"[{\"id\":0,\"username\":\"test\"},{\"id\":8,\"username\":\"testuser\"}]"
next lets have strucure type called 'User' like below:
public class User
{
public int Id { get; set; }
public string Username{ get; set; }
}
finally do Deserialize:
string str = "[{\"id\":0,\"username\":\"test\"},{\"id\":8,\"username\":\"testuser\"}]";
User[] res = Newtonsoft.Json.JsonConvert.DeserializeObject<User[]>(str);
Now you are able to do 'foreach' loop on res array.

Deserialize JSON with Unquoted Hexadecimal Values

Is there a way to deserialize some JSON to a DTO where the JSON contains unquoted hexadecimal values? I'm using JsonConvert.DeserializeObject.
This is the JSON that I need to deserialize. It is being produced by a device, and I don't have any control over it:
{"ID":7,"T":1511819861,"E":777, "ET":2,"DEVID":f525873c,"DEVTS":1511801849}
The problem is with the field "DEVID".
I know that this JSON is considered invalid, but I need to find a way to work with it. Is there any way to configure or cast that field?
As you don't have access to fix the response, I'd suggest you to fix the json before deserializing it. I did this function that might give you a hint how to fix your issue:
public static string FixJson(string json, string property) {
var index = json.IndexOf(property);
var indexColon = json.IndexOf(':', index + 1);
var indexComma = json.IndexOf(',', index + 1);
var val = json.Substring(indexColon + 1, indexComma - indexColon - 1);
var replace = string.Format("'{0}': {1}", property, val.Trim());
var forR = string.Format("'{0}': '{1}'", property, val.Trim());
return json.Replace(replace, forR);
}
You cant test it on
https://dotnetfiddle.net/kidAIO

Is "[]" valid JSON?

I'm having troubles de-serializing this JSON string using JSON.NET (note the quotes):
"[]"
Depending on which JSON validation website you go to, this is valid JSON (jsonlint for example says it is).
The JSON.NET code:
void Main()
{
string json = "\"[]\"";
var x = JsonConvert.DeserializeObject<User[]>(json);
Console.WriteLine(x);
}
// Define other methods and classes here
public class User
{
public string Id { get; set; }
public int Age { get; set; }
}
The exception
Error converting value "[]" to type 'UserQuery+User[]'. Path '', line 1, position 4.
Is there a way of forcing JSON.NET to parse this?
Part 1: Is "[]" valid JSON?
There are several documents and standards on JSON, and hundreds of parsers; and some of them suppose that JSON can only be object {} or an array [], but some allow single values like strings, numbers to be used as JSON.
Read this article, it widely describes this problem.
What is the minimum valid JSON?
This dispute on JSON validity is another question. In your case, it doesn't matter, because...
Part 2: why your code isn't working.
Even if we allow non-objects \ non-arrays to be valid JSON, then your JSON represents a single string equal to "[]". It could be anything else, not brackets, it is not an array notation, but just two symbols "[" and "]".
However, you try to parse this JSON as an array of objects, which will anyway result into error.
In other words, even if it is a valid JSON, then it is a valid JSON string, not JSON array.
var str1 = JSON.parse("\"[]\""),
str2 = JSON.parse("\"could be anything else, not brackets\""),
arr = JSON.parse("[]");
console.log(typeof str1);
console.log(typeof str2);
console.log(typeof arr);
var str1_s = JSON.stringify([]);
console.log("Valid JSON of an empty array: " + str1_s);
var arr_s = JSON.stringify("[]");
console.log("Partly valid JSON of a string '[]': " + arr_s);
Part 3: what should you do
The best idea - stop using invalid JSON as input. Tell whoever gave you this JSON that it is invalid JSON array and you cannot use it. You would be able to deserialize a JSON into your array of User if it was correct just like you use it:
string json = "[]";
var x = JsonConvert.DeserializeObject<User[]>(json);
Console.WriteLine(x);
If this JSON is provided from 3rd party services and you can do nothing about that, then you need to tidy it up and make it valid. Yeah, unfortunately, sometimes it happens.
How? It depends on what is your value when there ARE objects (users).
It may be a JSON-serialized JSON-string (double-serialized) like this, and then you need to deserialize a string, and then deserialize an array.
Or it can just have two odd quotes in the beginning and the end, and you can just remove them.
It is valid JSON, but the deserializer failes because the datatypes do not match.
"[]"
Is a string, so the deserializer wants to serialize it to a string.
[]
Is an empty array. So, in short, this should work:
string json = "[]";
var x = JsonConvert.DeserializeObject<User[]>(json);
Console.WriteLine(x);

How to deserialize Json in a Json?

Here is my json returned by php web application:
{"subtotal":475,"tax":47.5,"discount_section":[{"amount":237.5,"name":"test prior for percentage discount
"}],"grand_total_incl_tax":332.5}
I use c# and json.net to decode the abvoe json
var cart = webClient.DownloadString("http://localhost/m1/pos_addToCart.php?pidstr=" + pid_str);
dynamic result = JObject.Parse(cart);
But there is an error on this line:
order_discount_section.Text = result.discount_section;
Error:
Cannot implicitly convert type 'Newtonsoft.Json.Linq.JToken' to 'string'
How to convert this json to String like:
Key1 = Value1
Key2 = Value2
Key3 = Value3
Based upon your supplied json discount_section is a map so it can't be expressed as a string. It's like trying to convert a dictionary to a string or an array to a string.
If you want it as a string representation then adding ToString() after the result.discount_section (i.e. result.discount_section.ToString()) should accomplish that.
Though I would suggest that you either store the data through placeholder values such as:
string name = result.discount_section[0].name (same with amount but float/decimal/double...).
Or if you wanted it as text have it as
text = "Name: " + result.discount_section[0].name
+ "Amount: " + result.discount_section[0].amount.ToString();`
Obviously using a stringbuilder or other tool would be better (such as string.format) but I'll leave that as an 'exercise' to you.
Edit:
The for loop for all of the results.
totalText = ""
for (i = 0; i < result.discount_section.length; i++) {
totalText += "Name: " + result.discount_section[i].name + "Amount: " + result.discount_section[i].amount.ToString() + "\n";
}
Obviously if you wanted an array of strings then you would just build an array then just use i as your string array index as well.
Json.NET provides a correct behaviour.
As from your example string, it can be seen, that discount_section is a json array, or JArray, descendant of JToken after parsing to JObject.
If you want to access inner member of this array, as name for example, you should call it as
order_discount_section.Text = result.discount_section[0].name;
If you want to write the full notation of discount_section as is, you should explicitly call ToString method:
order_discount_section.Text = result.discount_section.ToString();
Although, dealing with dynamics is not useful, while your working with separate service responsing in JSON. It will be better to define a single class, which will handle json values, so you could not only look what json is passing, but to work with it
You may consider working with objects and deserialize using JsonConvert.DeserializeObject. Example:
class Discount
{
public Decimal Amount { get; set; }
public String Name { get; set; }
}
class Response
{
public Decimal Subtotal { get; set; }
public Decimal Tax { get; set; }
public List<Discount> Discount_section { get; set; }
public Grand_total_incl_tax { get; set; }
}
var response = JsonConvert.DeserializeObject<Response>(cart);
This approach is good when object structure is relatively fixed and has the following advantages:
clear structure
relevant errors when you have a type mismatch (JSON -> property)
result.discount_section is collection. you can not set directly to string variable.
try this.
var result= JObject.Parse(cart);
dynamic[] discountSection = result["discount_section"].ToArray<dynamic>();
decimal amount = discountSection[0].amount;
decimal name = discountSection[0].name;
for dictionary
Dictionary<string,decimal> discountDictionary = discountSection.ToDictionary<dynamic, string, decimal>((d) => d.name, (d) => d.amount);

C# JSONConvert.DeserializeObject JSON with Newlines

I have the following sample JSON in a variable called JSONContent
[
{"comment":"This is \\na comment"},
{"comment":"This is another comment"}
]
I type the JSON as such:
public class Comments
{
[JsonProperty("comment")]
public string comment { get; set; }
}
And Deserialize as such:
var Result = JsonConvert.DeserializeObject<List<Comments>>(JSONContent);
I then loop through the RESULT:
// Loop through the JSON object and populate the rows
foreach (var message in Result)
{
doSomething( message.comment );
}
When I inspect the message.comment it shows as:
This is \\na comment
This is another comment
What happens later is I am saving the comment into a database but the database shows the literal "\n" in the result instead of the hopeful newline. This is of course because c# is just converting the \\ to a literal \ and ignoring the n.
I know I can do a replace on the comment, but it feels like I am missing something that tells JSONConvert.DeserializeObject to do this for me.

Categories