I'm working with Json.Net to parse an array. What I'm trying to do is to pull the name/value pairs out of the array and assign them to specific variables while parsing the JObject.
Here's what I've got in the array:
[
{
"General": "At this time we do not have any frequent support requests."
},
{
"Support": "For support inquires, please see our support page."
}
]
And here's what I've got in the C#:
WebRequest objRequest = HttpWebRequest.Create(dest);
WebResponse objResponse = objRequest.GetResponse();
using (StreamReader reader = new StreamReader(objResponse.GetResponseStream()))
{
string json = reader.ReadToEnd();
JArray a = JArray.Parse(json);
//Here's where I'm stumped
}
I'm fairly new to JSON and Json.Net, so it might be a basic solution for someone else. I basically just need to assign the name/value pairs in a foreach loop so that I can output the data on the front-end. Has anyone done this before?
You can get at the data values like this:
string json = #"
[
{ ""General"" : ""At this time we do not have any frequent support requests."" },
{ ""Support"" : ""For support inquires, please see our support page."" }
]";
JArray a = JArray.Parse(json);
foreach (JObject o in a.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
string name = p.Name;
string value = (string)p.Value;
Console.WriteLine(name + " -- " + value);
}
}
Fiddle: https://dotnetfiddle.net/uox4Vt
Use Manatee.Json
https://github.com/gregsdennis/Manatee.Json/wiki/Usage
And you can convert the entire object to a string, filename.json is expected to be located in documents folder.
var text = File.ReadAllText("filename.json");
var json = JsonValue.Parse(text);
while (JsonValue.Null != null)
{
Console.WriteLine(json.ToString());
}
Console.ReadLine();
I know this is about Json.NET but times are a-changing so if anybody stumbles here while using .NET Core/5+ System.Text.Json please don't despair because
Try the new System.Text.Json APIs from .NET Blog show an example of this.
[
{
"date": "2013-01-07T00:00:00Z",
"temp": 23,
},
{
"date": "2013-01-08T00:00:00Z",
"temp": 28,
},
{
"date": "2013-01-14T00:00:00Z",
"temp": 8,
},
]
...
using (JsonDocument document = JsonDocument.Parse(json, options))
{
int sumOfAllTemperatures = 0;
int count = 0;
foreach (JsonElement element in document.RootElement.EnumerateArray())
{
DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();
(...)
Related
I receive a JSON file like this:
{
"Name": "testeName",
"type": "unique",
"TestData": [{
"price": 2.3
}]
}
I want to add a new property ("type":"unique") to each object in TestData to be like this in the end:
{
"Name": "testeName",
"type": "unique",
"TestData": [{
"price": 2.3,
"type": "unique"
}]
}
Is there any way to do it with less code? I try this but there's a lot of code, I believe there must be a simpler way:
using (MemoryStream memoryStream1 = new MemoryStream())
{
using (Utf8JsonWriter utf8JsonWriter1 = new Utf8JsonWriter(memoryStream1))
{
using (JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader))
{
utf8JsonWriter1.WriteStartObject();
foreach (var element in jsonDocument.RootElement.EnumerateObject())
{
if (element.Name == "price")
{
// Copying existing values from "TestData" object
foreach (var testDataElement in element.Value.EnumerateArray())
{
utf8JsonWriter1.WritePropertyName(element.Name);
// Staring new object
utf8JsonWriter1.WriteStartObject();
// Adding "Name" property
utf8JsonWriter1.WritePropertyName("type");
utf8JsonWriter1.WriteStringValue("unique");
//System.InvalidOperationException : 'Cannot write the start of an object or array without a property name. Current token type is 'String'.'
testDataElement.WriteTo(utf8JsonWriter1);
}
utf8JsonWriter1.WriteEndObject();
}
else
{
element.WriteTo(utf8JsonWriter1);
}
}
utf8JsonWriter1.WriteEndObject();
}
}
var resultJson = Encoding.UTF8.GetString(memoryStream1.ToArray());
}
you can try this code
using Newtonsoft.Json;
var jsonObject = JObject.Parse(json);
var testDataObj = (JObject) ((JArray)jsonObject["TestData"])[0];
testDataObj.Add("type", "unique");
json=jsonObject.ToString();
result
{
"Name": "testeName",
"type": "unique",
"TestData": [
{
"price": 2.3,
"type": "unique"
}
]
}
Can you use the Newtonsoft JSON Nuget package?
You can read JSON from a file, then use the JObject.Add method to add a property and value to the JSON object:
using (StreamReader file = File.OpenText("[insert your file path here]"))
using (JsonTextReader jtReader = new JsonTextReader(file))
{
JObject jObj = (JObject)JToken.ReadFrom(reader);
jObj.Add("type", "unique");
}
In .NET 6 and later you may use the new JsonNode editable JSON Document Object Model to load, modify and re-serialize your JSON:
// Load the file
JsonObject root;
using (var stream = File.OpenRead(inputFileName))
{
root = (JsonNode.Parse(GetJson()) ?? new JsonObject()).AsObject();
}
// Add "type" to "TestData[*]"
if (root["TestData"] is JsonArray array)
{
foreach (var obj in array.OfType<JsonObject>())
{
obj["type"] = "unique";
}
}
//Examine the resulting JSON string
var resultJson = root.ToString();
//Or write back the file directly, without using an intermediate JSON string
using (var stream = File.Create(outputFileName))
using (var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
{
root.WriteTo(writer);
}
Demo fiddle here.
i have a json-string, or bit more something like a "string of arrays":
"[
{
"type":"radio-group",
"label":"Radio-Button-Gruppe",
"name":"radio-group-1556028993486",
"className":"iCheck",
"values":[
{
"label":"aaaaaaa",
"value":"aaaaaaa"
},
{
"label":"bbbbbbbbb",
"value":"bbbbbbbbb"
},
{
"label":"cccccccccccc",
"value":"cccccccccccc"
}
]
}
],
[
...
],
[
{
"type":"header",
"label":"Ăberschrift"
}
]"
Now I want to have a List<string> of each array in this string. Something like:
List<string> x[0] = "{
"type":"radio-group",
"label":"Radio-Button-Gruppe",
"name":"radio-group-1556028993486",
"className":"iCheck",
"values":[
{
"label":"aaaaaaa",
"value":"aaaaaaa"
},
{
"label":"bbbbbbbbb",
"value":"bbbbbbbbb"
},
{
"label":"cccccccccccc",
"value":"cccccccccccc"
}
]
}"
What's the best way to do that?
I already tried out JsonConvert.DeserializeObject<IEnumerable<string>>() but my problem is that he wants to deserialize my jsons to an object. But I want to keep them as a string und put them to my list.
Why I need a list of string for each array?
Because I use the json-strings inside the arrays to render a form. each array show you a page of the form, and the json is the data for rendering this form.
to render this form i have to go through a loop through all of this arrays and render the json in it for every page.
You can use JsonConvert.DeserializeObject<IEnumerable<JToken>>(json) where json is each of your top level arrays. Then you can iterate through the results and use .ToString() on each JToken object.
As others have pointed out, you don't have valid JSON, so I didn't try to give a solution to parse out the top level arrays.
var json = #"[
{
""type"":""radio-group"",
""label"":""Radio-Button-Gruppe"",
""name"":""radio-group-1556028993486"",
""className"":""iCheck"",
""values"":[
{
""label"":""aaaaaaa"",
""value"":""aaaaaaa""
},
{
""label"":""bbbbbbbbb"",
""value"":""bbbbbbbbb""
},
{
""label"":""cccccccccccc"",
""value"":""cccccccccccc""
}
]
}
]";
var arrays = new[] { json };
var objectsAsStrings = new List<string>();
foreach (var array in arrays)
{
var tokens = JsonConvert.DeserializeObject<IEnumerable<JToken>>(array);
foreach (var token in tokens)
{
objectsAsStrings.Add(token.ToString());
}
}
var json = "yourjson";
var jsonnew = "[" + json+ "]";
var list = JsonConvert.DeserializeObject<dynamic>(jsonnew);
var result = new List<string>();
foreach (var item in list)
{
var str = JsonConvert.SerializeObject(item);
result.Add(str);
}
You can use this , too.
I need to parse 2 different types of JSONs as shown below:
JSON 1:
{
"projects": [
{
"sno": "1",
"project_name": "Abs",
"project_Status": "Live"
},
{
"sno": "2",
"project_name": "Cgi",
"project_Status": "Live"
}
]
}
JSON 2:
[
{
"sno": "1",
"project_name": "Disc",
"project_Status": "Live"
},
{
"sno": "2",
"project_name": "Rol",
"project_Status": "Live"
}
]
I was parsing the JSON 2 as follows:
using (StreamReader streamReader = new StreamReader(Path.Combine(Path.GetTempPath(), "sample.json")))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
JObject jsonPayload = JObject.Load(reader);
jsonProfile = jsonPayload.ToString();
JObject json = JObject.Parse(jsonProfile);
}
}
}
Is it possible for me to modify this to check if the JSON is in type 1 or type 2 and then parse it to assign each project to a different JObject?
Unless your JSON is large (thousands of lines), I would dispense with the reader altogether. Instead, read the whole JSON file into a string using File.ReadAllText and parse it using JToken.Parse. From there it is easy to check whether you have an array (JSON 2) or an object containing an array (JSON 1) and then process accordingly:
string fileName = Path.Combine(Path.GetTempPath(), "sample.json");
string json = File.ReadAllText(fileName);
JToken token = JToken.Parse(json);
JArray array = (token.Type == JTokenType.Array) ? (JArray)token : (JArray)token["projects"];
foreach (JObject project in array)
{
Console.WriteLine("number: " + (string)project["sno"]);
Console.WriteLine("name: " + (string)project["project_name"]);
Console.WriteLine("status: " + (string)project["project_Status"]);
Console.WriteLine();
}
Fiddle: https://dotnetfiddle.net/lA87Xo
I am trying to parse a json and populate these values into an object with DataContractJsonSerializer. Having no luck with this yet.
The json is -
{
"0": [
547,
541,
507,
548,
519,
0
],
"1": [
573,
504
]
}
I have tried the following code:
try
{
string json = #"""0"":[547,541,507,548,519,0],""1"":[573,504]";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractSerializer(typeof(MyClass));
var jsonParsed = seraializer.ReadObject(memStream);
}
}
catch(Exception ex)
{
}
Always getting an exception that the data is invalid at the root. But online json validators say this is a valid json.
MyClass -
[DataContract]
public class MyClass
{
[DataMember]
public Dictionary<string, List<int>> values { get; set; }
}
Thanks Patrick for providing me a working solution with Newtonsoft. But just to learn , I want to see what am I doing wrong with DataContractJsonSerializer. The code below gives me no exception, but I am not getting any values after the parsing is complete.
string json = #"{""0"":[547,541,507,548,519,0],""1"":[573,504]}";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>));
var jsonParsed = seraializer.ReadObject(memStream);
}
You should use Dictionary<string, List<int>> as the type to deserialize to. You also need to use the right serializer (DataContractSerializer is for XML, DataContractJsonSerializer for JSON):
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>), new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true });
var jsonParsed = seraializer.ReadObject(memStream);
Or for JSON.NET:
var x = JsonConvert.DeserializeObject<Dictionary<string, List<int>>>(json);
I am not much of a C# Programmer so I am fairly new to this, I would like to parse the sample JSON below, I have been using the code:
WebClient client = new WebClient();
string getString = client.DownloadString(url);
dynamic j = JsonConvert.DeserializeObject(getString);
var k = j.rgDescriptions;
dynamic m = JsonConvert.DeserializeObject(k);
foreach (var c in m.descriptions)
{
Console.WriteLine(c);
}
I get error in deserialize of k, I am not sure if I am at the right path though. How do I get the "classid" w/o getting the value of their parent, because it is dynamic and not named, it is a Unique ID.
{
"success": true,
"rgDescriptions": {
"671219543": {
"id": "671219543",
"classid": "253033065",
"instanceid": "93973071",
"amount": "1",
"pos": 274
},
"707030894": {
"id": "707030894",
"classid": "166354998",
"instanceid": "0",
"amount": "1",
"pos": 277
},
Update:
I used this code:
WebClient client = new WebClient();
string getString = client.DownloadString(url);
var jo = JObject.Parse(getString);
var data = (JObject)jo["rgDescriptions"];
foreach (var item in data)
{
Console.WriteLine("{0}: {1}", item.Key, item.Value);
}
I could get what I wanted now, but I need to parse each value. Is there a better way?
You could use JSON.NET and JSONPath to query the incoming JSON, examples here and here
The code below extracts every classid for each object in rgDescriptions
//...
WebClient client = new WebClient();
string getString = client.DownloadString(url);
var obj = JObject.Parse(getString);
var classIds = obj.SelectTokens("$.rgDescriptions.*.classid").Select(x => x.Value<string>()).ToList(); //[253033065,166354998]
//Class ID Where...
var idToSearch = "671219543";
var classId = obj.SelectToken("$.rgDescriptions['" + idToSearch + "']..classid").Value<string>();
//...