How to deserialize a file with peculiar data set of JSON objects - c#

I'm trying to deserialize a file that contains data set of JSON objects that are not separated by commas
{
"passages": [
{
"is_selected": 1,
"url": "http://someUrl.com",
"passage_text": "someTextHere"
},
{
"is_selected": 0,
"url": "http://someUrl.com",
"passage_text": "someTextHere""
},
],
"query_id": 9749,
"answers": ["Here is the answer"],
"query_type": "description",
"query": "Here is my query"
}
{
"passages": [
{
"is_selected": 0,
"url": "http://someAnotherUrl.com",
"passage_text": "someAnotherTextHere"
},
{
"is_selected": 1,
"url": "http://someAnotherUrl.com",
"passage_text": "someAnotherTextHere""
},
],
"query_id": 0564,
"answers": ["Here is the another answer"],
"query_type": "another description",
"query": "Here is my another query"
}
I am trying to use this code with Newtonsoft.JSON deserialization but it returns an exception
"An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[JsonParser.DataSet]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly."
public class DataSet
{
public List<Passage> passages { get; set; }
public int query_id { get; set; }
public List<string> answers { get; set; }
public string query_type { get; set; }
public string query { get; set; }
public int Count { get; internal set; }
}
public class Passage
{
public int is_selected { get; set; }
public Uri url { get; set; }
public string passage_text { get; set; }
}
class Program
{
public static string jsonFileLocation = #"C:\my.json";
static void Main(string[] args)
{
using (StreamReader file = File.OpenText(jsonFileLocation))
{
JsonSerializer serializer = new JsonSerializer();
List<DataSet> data = (List<DataSet>)serializer.Deserialize(file, typeof(List<DataSet>));
}
}
}
I do not think it's a good idea to place commas and brackets manually to bring the file to JSON format because this file contains several thousand records.
Have you any ideas how to parse and deserialize this file?

If the file is consistent in that each JSON node is separated by a new line character, you could first stream the file into a System.String and replace all instances of:
}
{
with:
},
{
Then, deserialize the JSON string. This is just one idea.

Related

Deserialize complex JSON object fails to see collection

I've simplified the code (below) but I cannot figure out why the Result.Data property is not getting filled; it is always null. I've used jsonlint.com to validate the JSON (both this small sample and the full content). I built a separate project (using How to Deserialize a Complex JSON Object in C# .NET) and it successfully serializes the complex object listed there. But I cannot get this one to work and I'm stumped.
using System.Text.Json;
namespace JsonTest2;
public class Result
{
public string? Total { get; set; }
public string? Limit { get; set; }
public string? Start { get; set; }
protected List<Park>? Data { get; set; }
}
public class Park
{
public string? Id { get; set; }
}
internal class Program
{
var basepath = AppDomain.CurrentDomain.BaseDirectory;
var filepath = basepath.Split("\\bin")[0];
var filename = #$"{filepath}\NPS_response_small.json";
var jsonstr = File.ReadAllText(filename);
var response = JsonSerializer.Deserialize<Result>(jsonstr, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
}
This is the content of "NPS_response_small.json":
{
"total": "468",
"limit": "50",
"start": "0",
"data": [
{
"id": "77E0D7F0-1942-494A-ACE2-9004D2BDC59E"
},
{
"id": "6DA17C86-088E-4B4D-B862-7C1BD5CF236B"
},
{
"id": "E4C7784E-66A0-4D44-87D0-3E072F5FEF43"
}
]
}
you have to chanbe a protected attribute of property Data to a public. Json deserializer doesnt have any acces to this property
public List<Park>? Data { get; set; }
it would be much easier to use Newtonsoft.Json, but if you need protected for some reason, you can try this ( but I am not sure that it is a full replacement)
public List<Park>? Data { protected get; init ; }
[System.Text.Json.Serialization.JsonConstructor]
public Result (List<Park>? Data, string? Total, string? Limit, string? Start)
{
this.Data=Data;
this.Total=Total;
this.Limit=Limit;
this.Start=Start;
}

Exception occurs while deserialize json containing date with different format C#

Having json string containing date field
{
"totalSize": 2,
"records": [
{
"Id": "5006C000008ZhEDQA0",
"CreatedDate": "2021-12-01T15:14:20.000+0000",
"CaseNumber": "01378682",
"Status": "Open"
},
{
"Id": "5006C000008ZhE00A0",
"CreatedDate": "2021-12-05T08:00:00.000+0000",
"CaseNumber": "01378692",
"Status": "Open"
}
]
}
I'm trying to do normal Deserialization where CreatedDate datatype is DateTime.
JsonSerializer.Deserialize<SFHistoryResponse>(stringResponse);
I'm getting
The JSON value could not be converted to System.DateTime. Path:
$.records[0].CreatedDate
is there any way to format JSON's date part before Deserialization
The Newtonsoft JSON library can deserialize the string properly without throwing an exception:
using Newtonsoft.Json;
var response = JsonConvert.DeserializeObject<SFHistoryResponse>(stringResponse);
In your case your classes need to be:
public class Record
{
public string Id { get; set; }
public DateTime CreatedDate { get; set; }
public string CaseNumber { get; set; }
public string Status { get; set; }
}
public class SFHistoryResponse
{
public int totalSize { get; set; }
public List<Record> records { get; set; }
}
and when you try to deserialize the json
SFHistoryResponse l = JsonConvert.DeserializeObject<SFHistoryResponse>(jsonString);
tested my self
tbResult.Text = "l.records[0].CreatedDate.ToString() - " + l.records[0].CreatedDate.ToString();

Having issues reading a JSON file in C#

I am a novice in C# and I am having issues reading a JSON file.
The JSON file follows this format:
{
"info": {
"year": 2020,
"version": "1.0",
"description": "fake description",
"date_created": "2020-04-31T20:32:11.8958473Z"
},
"licenses": [
{
"name": "fake name",
"id": 2020
}
],
"images": [
{
"id": 1,
"width": 1280,
"height": 720,
"filename": "filename1.jpeg",
"license": 1
},
{
"id": 2,
"width": 1280,
"height": 720,
"filename": "filename2.jpeg",
"license": 2
},
...
For now I am trying to read the Images section in the JSON file. Here is my class for it:
public class Images
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("width")]
public int width { get; set; }
[JsonProperty("height")]
public int height { get; set; }
[JsonProperty("filename")]
public string filename { get; set; }
[JsonProperty("license")]
public int license { get; set; }
}
public class Image_json
{
[JsonProperty("images")]
public Image Image_json { get; set; }
}
In my main class, I try deserializing it here:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace C__Playground
{
public class read_json
{
static void Main(string[] args)
{
using (StreamReader r = new StreamReader("COCOExport.json"))
{
string json = r.ReadToEnd();
var test1 = JsonConvert.DeserializeObject<List<Image_json>(json);
}
}
}
}
When I try to run the program, I get this message:
Unhandled exception. Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[C__Playground.Image_jsonJson]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
I have been following this post here.
I tried using the solution here but it returns empty or I receive a null error. Any insights?
Your problem should be here:
public class Image_json
{
[JsonProperty("images")]
public Image_json Image_json { get; set; }
}
This property is of type Image_json, which is the same as the containing class. You need a collection of Images. Could be an array or a List<Images>.
public class Image_json
{
[JsonProperty("images")]
public List<Images> Image_json { get; set; }
}
BTW, the Images class should be called Image since it holds a single image, not a collection of them.
Please find below code.
Class Images:
public class Images
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("width")]
public int width { get; set; }
[JsonProperty("height")]
public int height { get; set; }
[JsonProperty("filename")]
public string filename { get; set; }
[JsonProperty("license")]
public int license { get; set; }
}
class ImageJson:
public class ImageJson
{
[JsonProperty("images")]
public List<Images> Image_json // We shoild use list of images
{
get; set;
}
}
To test output:
using (StreamReader r = new StreamReader("COCOExport.json"))
{
string json = r.ReadToEnd();
var test1 = JsonConvert.DeserializeObject<ImageJson>(json);
foreach(var output in test1.Image_json)
{
Console.WriteLine(output.id);
Console.WriteLine(output.width);
Console.WriteLine(output.height);
Console.WriteLine(output.filename);
Console.WriteLine(output.license);
}
Console.ReadLine();
}
It is alwasy good practice to use PascalCasing for Properties.
Ex:)
[JsonProperty("id")]
public int Id { get; set; }
Please find solution here. Explained in a video
https://www.youtube.com/watch?v=nHtdReIhvag

Deserializing a serialized JSON file

I have a JSON file that has been serialized through an API, in which I need to deserialize it to use the data it generated in my code. The issue is that I'm getting an Exception Unhandled error in which I have tried to understand the solution to the error, but I have had a few days off tunnel vision with this issue.
I have tried my best to link my issue with other threads, but have been lost for a few days. I did get some form of sprint finish with setting up a {get { return } } with a property but due to the setup of the code when serializing I couldn't do that. Instead I've tried to put the file outputted in a simple location and tried desalinizing it based on the file location.
ImageModeration image1 = JsonConvert.DeserializeObject<ImageModeration>(File.ReadAllText(#"C:\ModerationOutput.json"));
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(#"C:\ModerationOutput.json"))
{
JsonSerializer serializer = new JsonSerializer();
ImageModeration image2 = (ImageModeration)serializer.Deserialize(file, typeof(ImageModeration));
}
Here is my json file
[
{
"ImageUrl": "URL",
"ImageModeration": {
"CacheID": "396a972f-79ae-4b31-a54c-0ba3314318fa_637026883058218816",
"Result": false,
"TrackingId": "UKS_ibiza_464a60be-f57d-4ee1-aa37-13d04f151fdd_ContentModerator.F0_4ae15371-36c9-4cb2-8e21-83381a29432c",
"AdultClassificationScore": 0.0048455675132572651,
"IsImageAdultClassified": false,
"RacyClassificationScore": 0.011258091777563095,
"IsImageRacyClassified": false,
"AdvancedInfo": [
{
"Key": "ImageDownloadTimeInMs",
"Value": "37"
},
{
"Key": "ImageSizeInBytes",
"Value": "34854"
}
],
"Status": {
"Code": 3000,
"Description": "OK",
"Exception": null
}
},
"TextDetection": null,
"FaceDetection": null
}
]
This error comes from the first line of code.
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array (e.g. [1,2,3]) into type
'convertingJSON.Program+ImageModeration' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix
this error either change the JSON to a JSON object (e.g.
{"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array.
JsonArrayAttribute can also be added to the type to force it to
deserialize from a JSON array. Path '', line 1, position 1.'
Specific to your JSON string that you have posted, you can refer to the following code snippet to deserialize your string into its respective components.I am using the Newtonsoft JSON library which is a popular high-performance JSON framework for .NET. A working example can be found at: https://dotnetfiddle.net/RmXNHM
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string json=#"[{'ImageUrl':'URL','ImageModeration':{'CacheID':'396a972f-79ae-4b31-a54c-0ba3314318fa_637026883058218816','Result':false,'TrackingId':'UKS_ibiza_464a60be-f57d-4ee1-aa37-13d04f151fdd_ContentModerator.F0_4ae15371-36c9-4cb2-8e21-83381a29432c','AdultClassificationScore':0.004845567513257265,'IsImageAdultClassified':false,'RacyClassificationScore':0.011258091777563095,'IsImageRacyClassified':false,'AdvancedInfo':[{'Key':'ImageDownloadTimeInMs','Value':'37'},{'Key':'ImageSizeInBytes','Value':'34854'}],'Status':{'Code':3000,'Description':'OK','Exception':null}},'TextDetection':null,'FaceDetection':null}]";
var Sresponse = JsonConvert.DeserializeObject<List<RootObject>>(json);
foreach(var value1 in Sresponse)
{
Console.WriteLine(value1.ImageUrl);
Console.WriteLine(value1.ImageModeration.CacheID);
}
}
}
public class AdvancedInfo
{
public string Key { get; set; }
public string Value { get; set; }
}
public class Status
{
public int Code { get; set; }
public string Description { get; set; }
public object Exception { get; set; }
}
public class ImageModeration
{
public string CacheID { get; set; }
public bool Result { get; set; }
public string TrackingId { get; set; }
public double AdultClassificationScore { get; set; }
public bool IsImageAdultClassified { get; set; }
public double RacyClassificationScore { get; set; }
public bool IsImageRacyClassified { get; set; }
public List<AdvancedInfo> AdvancedInfo { get; set; }
public Status Status { get; set; }
}
public class RootObject
{
public string ImageUrl { get; set; }
public ImageModeration ImageModeration { get; set; }
public object TextDetection { get; set; }
public object FaceDetection { get; set; }
}
Output:
URL
396a972f-79ae-4b31-a54c-0ba3314318fa_637026883058218816
Use this site to convert you're JSON to a C# object and then deserialize to it.
According to the error it seems you may have been missing a property i.e. the object does not correspond to the JSON

C# Newtonsoft deserialize JSON array

I'm trying to deserialize an array using Newtonsoft so i can display files from a cloud based server in a listbox but i always end up getting this error no matter what i try:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: [. Path '[0].priv', line 4, position 15.'
Thisis an example try to deserialize:
[
{
"code": 200,
"priv": [
{
"file": "file.txt",
"ext": "txt",
"size": "104.86"
},
{
"file": "file2.exe",
"ext": "exe",
"size": "173.74"
},
],
"pub": [
{
"file": "file.txt",
"ext": "txt",
"size": "104.86"
},
{
"file": "file2.exe",
"ext": "exe",
"size": "173.74"
}
]
}
]
I tried using a C# Class like this:
public class ListJson
{
[JsonProperty("pub")]
public List List { get; set; }
}
public class List
{
[JsonProperty("file")]
public string File { get; set; }
[JsonProperty("ext")]
public string Ext { get; set; }
[JsonProperty("size")]
public string Size { get; set; }
}
[JsonProperty("priv")]
public List List { get; set; }
}
public class List
{
[JsonProperty("file")]
public string File { get; set; }
[JsonProperty("ext")]
public string Ext { get; set; }
[JsonProperty("size")]
public string Size { get; set; }
}
And deserialize with:
List<list> fetch = Newtonsoft.Json.JsonConvert.DeserializeObject<List<list>>(json);
The correct C# class structure for your JSON is the following:
public class FileEntry
{
public string file { get; set; }
public string ext { get; set; }
public string size { get; set; }
}
public class FileList
{
public int code { get; set; }
public List<FileEntry> priv { get; set; }
public List<FileEntry> pub { get; set; }
}
Deserializing it in this way:
var fetch = JsonConvert.DeserializeObject<FileList[]>(json);
var fileList = fetch.First(); // here we have a single FileList object
As said in the other answer, creating a class called List doesn't automagically turn it into a collection of objects. You need to declare the types to be deserialized from an array a collection type (e.g. List<T>, T[], etc.).
Small tip: when in doubt, use json2csharp.com to generate strongly typed classes from a json string.
At the moment List has a single List instance called priv, which despite the name: doesn't make it a list. To deserialize a JSON array ("priv": [...]), it needs to an array or list-like type, for example List<T> for some T. Presumably a List<FileThing>, if we assume that FileThing is actually the second type called List (you have 2).

Categories

Resources