I am working on JArray in .NET CORE and I am getting random structure of this one specific key, hence getting different error. I need to know if JArray has specific child Array and if Child JArray have specific key pair (NOT VALUE) i.e. value{ "Id":""} one of error is following;
Accessed JArray values with invalid key value: "id". Int32 array index expected.
at Newtonsoft.Json.Linq.JArray.get_Item(Object key) at
the standard structure I am expecting is as following;
{[value, [
{
"id": "7ef82869-e235-69a2-f81e-3a9664e89bc4",
"value": ""
}
]]}
sometime I get as, meaning throw null error where I am trying to map Id.
{[value, [
{
"value": ""
}
]]}
and some Time I don't get this property at all
I am trying following check to cover all scenario but Its not really working.
code
if (answerItems.value != null && answerItems.value.HasValues && answerItems.value["id"]!=null)
{
I received some constructive criticism on the brevity of my answer so I figured I would elaborate to help you through your issue.
First, let's take a look at your JSON. In short, it isn't valid. In fact, it isn't even close to valid JSON. I can only assume you meant something like this:
{
"values" : [{ "id" : "7ef82869-e235-69a2-f81e-3a9664e89bc4", "value": "" }]
}
I would suggest that anytime you are trying to parse data like this and you run into issues you start trouble shooting by validating the data itself. I like to use JSONLint for this.
Next, it is difficult from your example code to tell exactly what you are trying to do. I can only guess that you are attempting to use the dynamic object method of parsing and working with the data. A downside to this method is it is difficult to validate your data before you work with it.
Instead, I would use the Newtonsoft.Json.Linq.JObject.Parse method. This gives you some tools for working with and validating the information. Below I have included a very simple example of how this would be done.
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string json = "{ \"values\": [{ \"id\": \"7ef82869-e235-69a2-f81e-3a9664e89bc4\", \"value\": \"\" }] }";
JObject obj = JObject.Parse(json);
// Check to see if we got our value array
if (obj.ContainsKey("values")) {
JArray values = (JArray)obj["values"];
// Do we have any values in our array?
if (values.Count > 0) {
JObject firstItem = (JObject)values[0];
// We check to see if we have an ID parameter
if (firstItem.ContainsKey("id")) {
Console.WriteLine(firstItem["id"]);
}
}
}
}
}
As I mentioned in my original post, I would strongly recommend reviewing the Newtonsoft.Json documentation.
Related
i am working with two unknown json (i don't know structure) and i need to merge these two, i also have to remove missing properties, I know I probably haven't explained myself very well, so I'll give you an example.
Json 1:
{
'FullName': 'Dan Deleted',
'Deleted': true,
'DeletedDate': '2013-01-20T00:00:00',
'location': {
'nation': 'it',
'city': 'Madrid'
}
}
Json 2:
{
'FullName': 'Dan',
'Age': '23',
'DeletedDate': '2014-01-20T00:00:00',
'location': {
'nation': 'es'
}
what I would:
{
'FullName': 'Dan',
'Deleted': true,
'DeletedDate': '2014-01-20T00:00:00',
'location': {
'nation': 'es',
'city': 'Madrid'
}
}
I'm using Newtonsoft.Json and i've saw that there is a method merge json1.merge(json2) but in this way i will get something like that:
{
"FullName": "Dan",
"Deleted": true,
"DeletedDate": "2014-01-20T00:00:00",
"location": {
"nation": "es",
"city": "Madrid"
},
"Age": "23"
}
I hope you understand.
In practice I would like that if the property is present in both json, in the result the value is that of json2, but if a property is present only in json2, in the result this should not be there. While if it is only in json1 then it will be in the result.
How could I do?
Thank you very much!😃😃
According to Newtonsoft's example its a matter of which JObject it is invoked on and which other JObject is passed in as an argument. The one passed in by argument is the one that overwrites. Given these parameters, you will want to get the API responses as a string and then deserialize with JObject.Parse(string)
Also note that prior to the merge you can probably run some validation logic on these parsed objects to suit your needs
You should probably also explore the JsonMergeSettings object that is shown in the example, as it may include some finer grained options that you may want for your merge
I have a Json object coming into my WebApi. The structure can take any form. The only thing I know for certain is that somewhere in that structure (could be a top level node, could be a child node) I will have a node made up of:
"data": {
"mop": "1012346354462",
"fuelType": "E",
"Id": "1029dd56-10b1-46cb-9966-3c37e057a470",
"Status": "SecuredActive",
"StatusFromDate": "2020-11-20T17:00:00.000Z",
"ActiveDate": "2020-11-21T00:00:00.000Z",
"GeneratedReference": "1012346354462_1"
},
Can anyone help on how I can easily extract this bit of data from the JSon Object. I have a class that maps to these properties, but before I can use it I need to single this out from the rest of the JSON. I'm using C#
After much playing around, I've finally found a solution, so thought I'd post in-case others hit a similar issue.
JObject result = JObject.Parse(Request.ToString());
var clientarray = result["events"].Value<JArray>();
var blockIwant = clientarray.Children<JObject>().Select(x => x.Children<JProperty>().Where(y => y.Name == "data").First());
use JSON Convert to deserialize the object.
var Data = JsonConvert.DeserializeObject<dynamic>(data);
Then you can access using the Data object.
Eg : Console.WriteLine((String)Data.data.fuelTypereturn);
Gives the answer as "E"
I'm writing a Web API ApiController with several PUT methods that receive JSON data. The JSON is not deterministic and hence cannot be hard-mapped to a custom C# object, but needs to be received as Dictionaries/Sequences (Maps/Lists).
I have tried using an IDictionary for the data parm of the PUT method in the controller, and this sort of works -- the data appears to be mapped from JSON to the dictionary. However, it's necessary to declare the dictionary as <String,Object>, and there's no clear way to then retrieve the Object values as their appropriate types. (I've found a few suggested kluges in my searching, but they are just that.)
There is also a System.Json.JsonObject type which I finally managed to get loaded via NuGet, but when I use that the system does not appear to know how to map the data.
How is this typically done? How do you implement an ApiController method that receives generic JSON?
I can see three basic approaches:
Somehow make Dictionary/Sequence work with Object or some such.
Make something like System.Json.JsonObject work, perhaps by swizzling the routing info.
Receive the JSON as a byte array and then parse explicitly using one of the C# JSON toolkits available.
(As to how dynamic the data is, JSON objects may have missing entries or extraneous entries, and in some cases a particular entry may be represented as either a single JSON value or a JSON array of values. (Where "value" is JSON array, object, string, number, Boolean, or null.) In general, except for the array/not array ambiguity, the relation between keys and value types is known.)
(But I should note that this is a large project and I'll be receiving JSON strings from several other components by other authors. Being able to examine the received type and assert that it's as expected would be quite useful, and may even be necessary from a security standpoint.)
(I should add that I'm a relative novice with C# -- have only been working with it for about 6 months.)
You've got to know what kind of data you're expecting, but I have had success doing this in the past using dynamic typing.
Something like this:
[Test]
public void JsonTester()
{
string json = "{ 'fruit':'banana', 'color':'yellow' }";
dynamic data = JsonConvert.DeserializeObject(json);
string fruit = data["fruit"];
string color = data["color"];
Assert.That(fruit == "banana");
Assert.That(color == "yellow");
}
Edit:
You either need to know the type you want to deserialize to beforehand - in which case you can deserialize it to that type immediately.
Or you can deserialize it to a dynamic type, and then convert it to your static type once you know what you want to do with it.
using Newtonsoft.Json;
using NUnit.Framework;
public class DTO
{
public string Field1;
public int Field2;
}
public class JsonDeserializationTests
{
[Test]
public void JsonCanBeDeserializedToDTO()
{
string json = "{ 'Field1':'some text', 'Field2':45 }";
var data = JsonConvert.DeserializeObject<DTO>(json);
Assert.That(data.Field1 == "some text");
Assert.That(data.Field2 == 45);
}
[Test]
public void JsonCanBeDeserializedToDynamic_AndConvertedToDTO()
{
string json = "{ 'Field1':'some text', 'Field2':45 }";
var dynamicData = JsonConvert.DeserializeObject<dynamic>(json);
var data = new DTO { Field1 = dynamicData["Field1"], Field2 = dynamicData["Field2"] };
Assert.That(data.Field1 == "some text");
Assert.That(data.Field2 == 45);
}
}
I am trying to parse a json string returned from the xively feed from an Air Quality Egg. One of the properties says whether the xively feed is public or private. The property is called private and takes the string value "true" or "false". To get data from the feed I am calling xively's Historical Data REST API which successfully returns me valid JSON. I am then using JSON.NET to parse the JSON in C#. My parsing starts thus:
dynamic historicalDatapoints = JValue.Parse(jsonString) as JObject;
if (historicalDatapoints != null)
{
var id = historicalDatapoints.id;
var title = historicalDatapoints.title.ToString();
var privacy = bool.Parse(historicalDatapoints.private.ToString())
// More parsing
}
I have a problem with that last line of code. C# will not let me refer to the property called "private". Here's the corresponding (redacted) JSON:
{
"id": 000000843,
"title": "Blah Road Egg 02",
"private": "false",
//...
}
Using JSON.NET how should I parse out the property private?
Try historicalDatapoints.#private to access that value. If that doesn't work then you could also try historicalDatapoints["private"]
We are trying to write a way to consume a JSON feed from a third party but unfortunately it's not well written, there appears to be no rules on what is sometimes there or not and also the structure changes depending on the key, I have no way of changing this we have to work with what we have. We know what we want based on certain keys but we are struggling to find them as the nested structure changes.
Is it possible to flatten the JSON down to a single List> that we can query and the key would be the fully qualified name including parents so the following JSON:
{
"employees": [
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
}
Would become a list with keys like:
"employees.firstName" and a value of "John".
I think if we could get to this we could query the data for what we want, we have been trying to use dynamic objects but as I said the JSON changes and properties are missing sometimes and it's proving impossible to handle all scenarios.
If you don't know reliably the structure of a JSON but you are sure about property name ex "firstName". You can use the JSON.NET JObject and recursively loop through it and check if the property you are looking for exists in the current JToken.
The code should look something Like that, note the code I didn't compile it can have some typing mistakes:
private List<string> LoadFirstNames(string json)
{
JObject o = JObject.Parse(json);
List<string> firstNames = new List<string>();
foreach(var token in o.GetPropertyValues())
{
FindFirstName(token, firstNames);
}
return firstNames;
}
private void FindFirstName(JToken currentProperty, List<string> firstNamesCollection)
{
if(currentProperty == null)
{
return;
}
if(currentProperty["firstName"] != null)
{
firstNamesCollection.Add(currentProperty["firstName"]);
}
foreach(var token into currentProperty.Values())
{
FindFirstName(token , firstNamesCollection);
}
}