How to Parse this Json with Json.net? - json

I have this json:
{
"Message": "The request is invalid.",
"ModelState": {
"Email": [
"The Email field is required."
]
}
}
I want to find the ModelState(if it exists) and then loop through all the errors that re in there.
I can figure out how to do this. I don't want to make a concrete class as the data might change depending on what happens on the sever.
I also can use dynamic as I am on WPF7
JObject jsonObj = JObject.Parse(response.Content);
foreach (var j in jsonObj)
{
var t = j.Value;
}
this is what I have so far.

JObject jsonObj = JObject.Parse(response.Content);
var modelState = jsonObj["ModelState"];
if (modelState != null)
{
// The JSON contains a property called ModelState
// so we can start looping through it:
foreach (JProperty item in modelState)
{
Console.WriteLine(item.Name);
foreach (JValue error in item.Values())
{
Console.WriteLine(error);
}
}
}

Related

How can I deserialize an invalid json ? Truncated list of objects

My json file is mostly an array that contain objects but the list is incomplete, so I can't use the last entry. I would like to deserialize the rest of the file while discarding the last invalid entry
[ { "key" : "value1" }, { "key " : "value2"}, { "key
Please tell me if there is a way using Newtonsoft.Json library, or do I need some preprocessing.
Thank you!
Looks like on Json.NET 8.0.3 you can stream your string from a JsonTextReader to a JTokenWriter and get a partial result by catching and swallowing the JsonReaderException that gets thrown when parsing the truncated JSON:
JToken root;
string exceptionPath = null;
using (var textReader = new StringReader(badJson))
using (var jsonReader = new JsonTextReader(textReader))
using (JTokenWriter jsonWriter = new JTokenWriter())
{
try
{
jsonWriter.WriteToken(jsonReader);
}
catch (JsonReaderException ex)
{
exceptionPath = ex.Path;
Debug.WriteLine(ex);
}
root = jsonWriter.Token;
}
Console.WriteLine(root);
if (exceptionPath != null)
{
Console.WriteLine("Error occurred with token: ");
var badToken = root.SelectToken(exceptionPath);
Console.WriteLine(badToken);
}
This results in:
[
{
"key": "value1"
},
{
"key ": "value2"
},
{}
]
You could then finish deserializing the partial object with JToken.ToObject. You could also delete the incomplete array entry by using badToken.Remove().
It would be better practice not to generate invalid JSON in the first place though. I'm also not entirely sure this is documented functionality of Json.NET, and thus it might not work with future versions of Json.NET. (E.g. conceivably Newtonsoft could change their algorithm such that JTokenWriter.Token is only set when writing is successful.)
You can use the JsonReader class and try to parse as far as you get. Something like the code below will parse as many properties as it gets and then throw an exception. This is of course if you want to deserialize into a concrete class.
public Partial FromJson(JsonReader reader)
{
while (reader.Read())
{
// Break on EndObject
if (reader.TokenType == JsonToken.EndObject)
break;
// Only look for properties
if (reader.TokenType != JsonToken.PropertyName)
continue;
switch ((string) reader.Value)
{
case "Id":
reader.Read();
Id = Convert.ToInt16(reader.Value);
break;
case "Name":
reader.Read();
Name = Convert.ToString(reader.Value);
break;
}
}
return this;
}
Code taken from the CGbR JSON Target.
the second answer above is really good and simple, helped me out!
static string FixPartialJson(string badJson)
{
JToken root;
string exceptionPath = null;
using (var textReader = new StringReader(badJson))
using (var jsonReader = new JsonTextReader(textReader))
using (JTokenWriter jsonWriter = new JTokenWriter())
{
try
{
jsonWriter.WriteToken(jsonReader);
}
catch (JsonReaderException ex)
{
exceptionPath = ex.Path;
}
root = jsonWriter.Token;
}
return root.ToString();
}

JSON : Accessing (editing) value using dynamic key

I have a JSON Object which looks like :
{ "stepbystep": { "steps": { },
"step1": "This is a step"
}
}
I need to edit the value of "step1" using a function.
My function is
function editJSON(parsedJSON,key) // parsedJSON is the JSONObject,key = "stepbystep.step1"
{
parsedJSON[key] = "This is now step 1";
}
How do I access inner/deep values using dynamic keys ?
Access your json like this :
// $js has json
$response = json_decode($js,true);
$stepbystep=$response["stepbystep"];
foreach($stepbystep_arr AS $stepbystep_obj)
{
echo $stepbystep_obj['step1'];// here is your desired value
//if you want dynamic step1, step2... you can use for loop
//$n is count
for($i=1;$i<=$n;$i++)
{
$stepbystep_obj['step'.$i];
}
}

Taking out a text from a String as a Key from Json

I need to take out 1000 from this Key-Value Pair in node Js
"msg":"amamm : ErrorResponse {\"abcd1\":{\"Status\":\"E\",\"rem\":{\"Code\":\"1000\",\"message\":\"Unable to access your information at this time.(1000)\"}}}"
The JSON what you have posted is invalid. May be your JSON should be like the following:
var json = {
"msg": {
"amm": {
"ErrorResponse": {
"abcd1": {
"Status": "E",
"rem": {
"Code": "1000",
"message": "Unabletoaccessyourinformationatthistime.(1000)"
}
}
}
}
}
}
Then in node.js you have get the value using dot notation like as follows:
json.msg.amm.ErrorResponse.abcd1.rem.code
Will give you the value 1000
Assuming you can get the string
amamm : ErrorResponse {\"abcd1\":{\"Status\":\"E\",\"rem\":{\"Code\":\"1000\",\"message\":\"Unable to access your information at this time.(1000)\"}}}
by doing err.msg
You can get the json and then get the string you want. I copied the content of the msg into a variable str just to test the regex
var re = /\{.*?\}$/;
var str = 'amamm : ErrorResponse {\"abcd1\":{\"Status\":\"E\",\"rem\":{\"Code\":\"1000\",\"message\":\"Unable to access your information at this time.(1000)\"}}}';
var m;
if ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
var content = JSON.parse(m[0]);
console.log(content);
console.log(content.abcd1.rem.Code);
}
Here's a working example: http://jsfiddle.net/sger1gk6/

How do I pull out the JSON field I want using Jackson TreeNode and JsonNode?

I'm a little stumped why I can't pull the "Type" field out of my JSON stream to make a decision. It seems like this should be so easy.
I have the following JSON that I have as input:
[
{
"Institution":"ABC",
"Facility":"XYZ",
"Make":"Sunrise",
"Model":"Admission",
"SerialNumber":"",
"Revision":"1",
"Type":"ABC_Admission",
"ArchiveData":"<CSV file contents>"
}
]
In my Java I have a try-catch block with a JsonHolder class that implements Serializable to hold the JSON. Here's the Java I currently have:
try {
// Parse and split the input
JsonHolder data = JsonHolder.getField("text", input);
DataExtractor.LOG.info("JsonHolder data= " + data);
TreeNode node = data.getTreeNode();
DataExtractor.LOG.info("node size= " + node.size());
node = node.path("Type");
JsonNode json = (JsonNode) node;
DataExtractor.LOG.info("json= " + json.asText());
// code to decide what to do based on Type found
if (json.asText().equals("ABC_Admission")) {
// do one thing
} else {
// do something else
}
} catch (IOException iox) {
DataExtractor.LOG.error("Error extracting data", iox);
this.collector.fail(input);
}
When I run my code I get the following output (NOTE: I changed my package name where the class is to just for this output display)
25741 [Thread-91-DataExtractor] INFO <proprietary package name>.DataExtractor - JsonHolder data= [
{
"Institution":"ABC",
"Facility":"XYZ",
"Make":"Sunrise",
"Model":"Admission",
"SerialNumber":"",
"Revision":"1",
"Type":"ABC_Admission",
"ArchiveData":"<CSV file contents>"
}
]
25741 [Thread-91-DataExtractor] INFO <proprietary package name>.DataExtractor - node size= 1
25741 [Thread-91-DataExtractor] INFO <proprietary package name>.DataExtractor - json=
As you can see I don't get anything out. I just want to extract the value of the field "Type", so I was expecting to get the value "ABC_Admission" in this case. I would have thought the node path would separate out just that field from the rest of the JSON tree.
What am I doing wrong?
After consulting with another developer I found out the issue is my JSON is inside an array. So, I need to iterate over that array and then pull out the Type field from the object.
The updated code to resolve this is below:
try {
// Parse and split the input
JsonHolder data = JsonHolder.getField("text", input);
DataExtractor.LOG.info("JsonHolder data= " + data);
TreeNode node = data.getTreeNode();
String type = null;
// if this is an array of objects, iterate through the array
// to get the object, and reference the field we want
if (node.isArray()){
ArrayNode ary = (ArrayNode) node;
for (int i = 0; i < ary.size(); ++i) {
JsonNode obj = ary.get(i);
if (obj.has("Type")) {
type = obj.path("Type").asText();
break;
}
}
}
if (type == null) {
// Do something with failure??
}
DataExtractor.LOG.info("json= " + type);
if (type.equals("ABC_Admission")) {
// do one thing
else {
// do something else
}
} catch (IOException iox) {
DataExtractor.LOG.error("Error extracting data", iox);
this.collector.fail(input);
}

Add object to array in JSON

I am trying to add an object in an array to an item in a JSON object.
The result I am looking for is:
{ "AvailableFacets":[ "color", "sheenlevel" ],
"Selections":[
{ "Facet":"color", "Value":"red" },
{ "Facet":"color", "Value":"blue" }
]
}
but I get the error "TypeError: myJsonObject.Selection.push is not a function" when doing the following:
var testJson = function () {
var myJsonObject = $.parseJSON('{"AvailableFacets":["color", "sheenlevel"]}');
myJsonObject.Selection = "[]";
var newObject1 = $.parseJSON('{"Facet":"color", "Value":"red"}');
var newObject2 = $.parseJSON('{"Facet":"color", "Value":"blue"}');
myJsonObject.Selection.push(newObject1);
return myJsonObject;
};
What am I doing wrong?
"[]" !== []. Did that help? You are using the wrong types. Also you are looking for an output with "Selections" but you are attempting to define "Selection", but I assume that is a typo. This should work:
myJsonObject.Selection = [{"Facet":"color", "Value":"red"},{"Facet":"color", "Value":"blue"}];
But if you wanted to parse a string of JSON as JSON then just change
myJsonObject.Selection = "[]";
to:
myJsonObject.Selection = [];