I am facing a problem for parsing a JSON array in C#
{
"details" : [{
"state" : "myState1",
"place" : [{
"name" : "placeName",
"age" : 13
}
]
}, {
"state" : "myState2",
"place" : [{
"name1" : "placeName"
}
]
}, {
"state" : "myState3",
"place" : [{
"name2" : "placeName"
}
]
}
]
}
My code is:
static void Main(string[] args)
{
string txt = File.ReadAllText("MyJSONFile.txt");
JavaScriptSerializer ser = new JavaScriptSerializer();
var data = ser.Deserialize(txt);
}
public class Wrap
{
public List<Dictionary<string, object>> details { get; set; }
}
How can I read data from these dictionaries? Sometimes the JSON will include only 1 facility's details, but other times there are more than 30 items in the array. This data is being pulled from the database.
You may use the following C# classes structure:
public class Place
{
public string name { get; set; }
public int age { get; set; }
public string name1 { get; set; }
public string name2 { get; set; }
}
public class Detail
{
public string state { get; set; }
public List<Place> place { get; set; }
}
public class Root
{
public List<Detail> details { get; set; }
}
public class Program
{
static void Main(string[] args)
{
string txt = File.ReadAllText("MyJSONFile.txt");
JavaScriptSerializer ser = new JavaScriptSerializer();
var data = ser.Deserialize<Root>(txt);
Console.WriteLine(data.details.Count); // 3
Console.WriteLine(data.details[0].state); // myState1
Console.WriteLine(data.details[1].place.Count); // 1
Console.WriteLine(data.details[1].place[0].age); // 13
}
}
The class structure you are using is wrong.
You will have to use the structure as follows, which corresponds to your JSON.
This structure have been generated using json2csharp
public class Place
{
public string name { get; set; }
public int age { get; set; }
public string name1 { get; set; }
public string name2 { get; set; }
}
public class Detail
{
public string state { get; set; }
public List<Place> place { get; set; }
}
public class RootObject
{
public List<Detail> details { get; set; }
}
Now in your code you can de serialize this using Newtonsoft.Json as follows:
static void Main(string[] args)
{
string jsonText = System.IO.File.ReadAllText("MyJSONFile.txt");
var rootObj = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonText);
rootObj.details.ForEach(detail =>
{
Console.WriteLine(detail.state);
detail.place.ForEach(p =>
{
if (string.IsNullOrWhiteSpace(p.name) == false)
{
Console.WriteLine(p.name);
}
if (string.IsNullOrWhiteSpace(p.name1) == false)
{
Console.WriteLine(p.name1);
}
if (string.IsNullOrWhiteSpace(p.name2) == false)
{
Console.WriteLine(p.name2);
}
if (p.age > 0)
{
Console.WriteLine(p.age);
}
Console.WriteLine(string.Empty);
});
});
Console.ReadKey(true);
}
Related
I'm trying to call a web API (JSON/Csharp Console application) I did the same steps in the dotnet : https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient
However, when I'm trying to get only the property "NAME1", an error came up : The JSON value could not be converted to System.Collections.Generic.List. I could get all the json information but when Deserializing the result for getting only particular data such as NAME1 it doesn't work.
public partial class Result
{
public List<GAZETTEER_ENTRY> GAZETTEER_ENTRY { get; set; }
}
public partial class GAZETTEER_ENTRY
{
public string ID { get; set; }
public string NAME1 { get; set; }
}
class Program
{
private static readonly HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
await RunAsync();
}
private static async Task RunAsync()
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("key", "xxxxxx");
var streamTask = client.GetStreamAsync("https://api.os.uk/search/names/v1/find?query=coventry&fq=LOCAL_TYPE:Hospital");
var data = await JsonSerializer.DeserializeAsync<List<GAZETTEER_ENTRY>>(await streamTask);
foreach (var item in data)
{
Console.WriteLine(item.NAME1);
}
This is the JSON data:
"header" : {
"uri" : "https://api.os.uk/search/names/v1/find?query=coventry",
"query" : "coventry",
"format" : "JSON",
"maxresults" : 100,
"offset" : 0,
"totalresults" : 4134
},
"results" : [ {
"GAZETTEER_ENTRY" : {
"ID" : "osgb4000000074568994",
"NAMES_URI" : "http://data.ordnancesurvey.co.uk/id/4000000074568994",
"NAME1" : "Coventry",
"TYPE" : "populatedPlace",
"LOCAL_TYPE" : "City",
"COUNTRY" : "England",
}
}, {
"GAZETTEER_ENTRY" : {
"ID" : "osgb4000000019401618",
"NAMES_URI" : "http://data.ordnancesurvey.co.uk/id/4000000019401618",
"NAME1" : "Coventry Street",
"TYPE" : "transportNetwork",
"LOCAL_TYPE" : "Named Road",
"COUNTRY" : "England",
}
}, {
"GAZETTEER_ENTRY" : {
"ID" : "osgb4000000073321650",
"NAMES_URI" : "http://data.ordnancesurvey.co.uk/id/4000000073321650",
"NAME1" : "Coventry",
"TYPE" : "transportNetwork",
"LOCAL_TYPE" : "Railway Station",
"COUNTRY" : "England",
}
Try deserializing the json using this RootObject model:
public class RootObject
{
public ResultObject[] results { get; set; }
}
public class ResultObject
{
public GazetteerEntryObject GAZETTEER_ENTRY { get; set; }
}
public class GazetteerEntryObject
{
public string NAME1 { get; set; }
}
Do it this way
var data = await JsonSerializer.DeserializeAsync<RootObject>(await streamTask);
To retrieve the names, do it like this:
var names = data.results.Select(x => x.GAZETTEER_ENTRY.NAME1);
Your response classes should be like
public class SearchResult
{
public Header header { get; set; }
public List<Result> results { get; set; }
}
public class Header
{
public string uri { get; set; }
public string query { get; set; }
public string format { get; set; }
public int maxresults { get; set; }
public int offset { get; set; }
public int totalresults { get; set; }
}
public class Result
{
public GAZETTEER_ENTRY GAZETTEER_ENTRY { get; set; }
}
public class GAZETTEER_ENTRY
{
public string ID { get; set; }
public System.Uri NAMES_URI { get; set; }
public string NAME1 { get; set; }
public string TYPE { get; set; }
public string LOCAL_TYPE { get; set; }
public string COUNTRY { get; set; }
}
and the deserialize should be
var data = await JsonSerializer.DeserializeAsync<SearchResult>(await streamTask);
and access NAME1 of nth result
data.results[0].GAZETTEER_ENTRY.NAME1
if you find difficulty in comparing classes and json response, You can simply copy the json response and goto VS -> edit-> paste special -> paste json as classes. VS will auto generate classes for you.
I'm trying to grap json data from mongodb, put it into a class objec and then print one parameter to console, but I get this error :
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: O. Path '_id', line 1, position 10.'
My json looks like this:
{ "_id" : ObjectId("5d72b79c58011725b8b31b10"), "length" : NumberLong(957608), "
chunkSize" : 64512, "uploadDate" : ISODate("2019-09-06T19:46:42.058Z"), "md5" :
"3965979118e1302a7d19f609f38ede3e", "filename" : "C:\\Users\\kbu\\Downloads\\hve
m-er-vi.jpg", "metadata" : { "Beloeb" : "", "Overskrift" : "", "Gruppe" : "", "B
eskrivelse" : "", "Dato" : "6. september 2019", "Afsender" : "Lars" } }
I suspect, it has to do with my class, but I can't figure out what.
This is my code:
class Program
{
static void Main(string[] args)
{
var client = new MongoClient("mongodb+srv://*********:*********#kbucluster-oslh9.mongodb.net/test?retryWrites=true&w=majority");
var database = client.GetDatabase("test");
var collec = database.GetCollection<BsonDocument>("fs.files");
var filter = Builders<BsonDocument>.Filter.Empty;
var result = collec.Find(filter).ToList();
foreach(var doc in result)
{
Console.WriteLine(doc.ToJson());
RootObject bilag = JsonConvert.DeserializeObject<RootObject>(doc.ToJson());
Console.WriteLine(bilag.ID);
}
Console.ReadKey();
}
}
public class Metadata
{
public string Beloeb { get; set; }
public string Overskrift { get; set; }
public string Gruppe { get; set; }
public string Beskrivelse { get; set; }
public string Dato { get; set; }
public string Afsender { get; set; }
}
public class RootObject
{
public string ID { get; set; }
public string Length { get; set; }
public string ChunkSize { get; set; }
public string UploadDate { get; set; }
public string MD5 { get; set; }
public string Filename { get; set; }
public Metadata Metadata { get; set; }
}
}
You can use the following method
object dotnetObject = BsonTypeMapper.MapToDotNetValue(bsonDocument);
// Json mapped to default .Net objects
string json = Newtonsoft.Json.JsonConvert.SerializeObject(dotnetObject);
// Parsing as JObject
var jobject = JObject.Parse(json);
// Deserializing as your custom Type
var myObject = JsonConvert.DeserializeObject<MyType>(json);
you don't need json.net if you match the property names/types of the RootObject like this:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System;
namespace StackOverflow
{
public class Program
{
public class Metadata
{
public string Beloeb { get; set; }
public string Overskrift { get; set; }
public string Gruppe { get; set; }
public string Beskrivelse { get; set; }
public string Dato { get; set; }
public string Afsender { get; set; }
}
public class RootObject
{
[BsonId] // need to add this
public ObjectId ID { get; set; }
public int length { get; set; }
public double chunkSize { get; set; }
public DateTime uploadDate { get; set; }
public string md5 { get; set; }
public string filename { get; set; }
public Metadata metadata { get; set; }
}
private static void Main(string[] args)
{
var collection = new MongoClient("mongodb://localhost")
.GetDatabase("test")
.GetCollection<RootObject>("fs.files");
var result = collection.Find(Builders<RootObject>.Filter.Empty).ToList();
foreach (var doc in result)
{
Console.WriteLine(doc.ToJson());
Console.WriteLine("");
Console.WriteLine(doc.ID.ToString());
Console.Read();
}
}
}
}
You can't have functions in your JSON
"_id" :ObjectId("5d72b79c58011725b8b31b10"), "length" : NumberLong(957608),"uploadDate" : ISODate("2019-09-06T19:46:42.058Z")
Parse error on line 1:
{ "_id" : ObjectId("5d72b79c58
----------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'
1-Wrong value _id key : "what is ObjectId method in json"?
2-wrong name _id : beacause in RootObject class ,property is ID!
3- you must remove ObjectId , NumberLong , ISODate With their braces
{ "ID" : "5d72b79c58011725b8b31b10", "Length" : "957608", "
ChunkSize" : "64512", "UploadDate" : "2019-09-06T19:46:42.058Z", "MD5" :
"3965979118e1302a7d19f609f38ede3e", "FileName" : "C:\\Users\\kbu\\Downloads\\hve
m-er-vi.jpg", "Metadata" : { "Beloeb" : "", "Overskrift" : "", "Gruppe" : "", "B
eskrivelse" : "", "Dato" : "6. september 2019", "Afsender" : "Lars" } }
I Get json data from third party in json format.
I am trying to fetch RollId from "Id" and MType from "Data" in some cases
"Data" doesn't have fields it is kind of blank.
It's working when we have "Data". In case of blank it's not working.
any idea on this? Is there a better approach of doing this?
This is the Json
string json = #"{
'root': {
'_type': '_container',
'Class': '.key.PModel',
'Elements': {
'_type': 'array<element>',
'_data': [
{
'_type': 'element',
'Class': '.key.PElement',
'Id': {
'_type': 'testId',
'Class': '.key.PModel',
'RollId': '.key.7157'
},
'Data': {
'_type': 'p_model',
'Class': '.key.Unsupported',
'MType': '.TestMType',
'Version': {
'_type': 'test__version',
'Class': '.key.TestVersion',
}
}
},
{
'_type': 'element',
'Class': '.key.PElement',
'Id': {
'_type': 'TestId',
'Class': '.key.PModel',
'RollId': '.key.11261'
},
'Data': '.ref.root.Elements.0.Data'
},
{
'_type': 'element',
'Class': '.key.PElement',
'Id': {
'_type': 'TestId',
'Class': '.key.PModel',
'RollId': '.key.7914'
},
'Data': '.ref.root.Elements.0.Data'
}
]
}
}
}";
This is the Code
public class Program
{
static void Main(string[] args)
{
//it provide json
var testCont = thirdpartyapi();
var dataList = new List<TestResponse>();
foreach (var testData in testCont.Elements())
{
var data = new TestResponse();
data.col1 = Convert.ToInt32(testData.Id().RollId());
data.col2 = testData.Data().MType().ToString();
dataList.Add(data);
}
}
public class TestResponse
{
public int col1 { get; set; }
public string col2 { get; set; }
}
}
First, try to get a valid well-formed json. You can use this code beautify tool. Then you can automatically generate C# class using json2csharp. Finally as you have C# class you can apply if statements and check if property is null.
Generated C# wrapper:
public class Id
{
public string _type { get; set; }
public string Class { get; set; }
public string RollId { get; set; }
}
public class Datum
{
public string _type { get; set; }
public string Class { get; set; }
public Id Id { get; set; }
public object Data { get; set; }
}
public class Elements
{
public string _type { get; set; }
public List<Datum> _data { get; set; }
}
public class Root
{
public string _type { get; set; }
public string Class { get; set; }
public Elements Elements { get; set; }
}
public class RootObject
{
public int encoding_version { get; set; }
public Root root { get; set; }
}
If you want to pick only few fields from complex JSON, you can consider using Cinchoo ETL - an open source library
Sample below shows how to pick RollId and MType values from your json
using (var r = new ChoJSONReader("## YOUR JSON FILE PATH ##")
.WithJSONPath("$.._data")
.WithField("RollId", jsonPath: "$..Id.RollId", fieldType: typeof(string))
.WithField("MType", jsonPath: "$..Data.MType", fieldType: typeof(string))
)
{
foreach (var rec in r)
{
Console.WriteLine((string)rec.RollId);
Console.WriteLine((string)rec.MType);
}
}
Hope it helps.
The easiest way is use the DataContractJsonSerializer
Here you can read more about it.
All in all you need to create a model which has the same possible outcome as your json.
Then you can just use the DataContractJsonSerializer to create an object of you model by using a MemoryStream.
Here you can find a nice tool to create the model from the JSON.
For example this one:
public class Id
{
public string _type { get; set; }
public string Class { get; set; }
public string RollId { get; set; }
}
public class Datum
{
public string _type { get; set; }
public string Class { get; set; }
public Id Id { get; set; }
public object Data { get; set; }
}
public class Elements
{
public string _type { get; set; }
public List<Datum> _data { get; set; }
}
public class Root
{
public string _type { get; set; }
public string Class { get; set; }
public Elements Elements { get; set; }
}
public class RootObject
{
public int encoding_version { get; set; }
public Root root { get; set; }
}
Then you use the MemoryStream and the DataContractJsonSerializer to Create an object of RootObject from that JSON.
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
stream1.Position = 0;
RootObject rootObject = (RootObject)ser.ReadObject(stream1);
And yes, as Adriani6 mentiones - your JSON is invalid at this point:
"Data": {
"_type": "p_model",
"Class": ".key.Unsupported",
"MType": ".TestMType",
"Version": {
"_type": "test__version",
"Class": ".key.TestVersion",
}
There is a , at the end wich is not allowed.
I started to learn C# and some Json, I am trying to get this form of Json format:
Desired Output :
I have tried this:
static void Main(string[] args)
{
var myjason = new myJson
{
ContentDisposition = "",
md5 = "da855ff838250f45d528a5a05692f14e",
file_name = "MyFile.docx",
features = new[] { "te" },
te = new te { reports = new[] { "pdf", "xml" } },
// images = new img { { a.id = "7e6fe36e-889e-4c25-8704-56378f0830df", a.revision = 1 }, { a.id = "e50e99f3-5963-4573-af9e-e3f4750b55e2", a.revision = 1 } }
};
string json = JsonConvert.SerializeObject(myjason, Formatting.Indented);
Console.WriteLine(json);
}
public class myJson
{
public string ContentDisposition{ get; set; }
public string md5 { get; set; }
public string file_name { get; set; }
public string[] features { get; set; }
public te te { get; set; }
public img images { get; set; }
}
public class a
{
public string id { get; set; }
public int revision { get; set; }
}
public class te
{
public string[] reports { get; set; }
}
public class img
{
public a[] images { get; set; }
}
And here is my current output:
Current output:
Please help, thanks a lot!
I think you are a bit confused about what's going on here. It looks like you're trying to POST some JSON to some endpoint.
Content-Disposition and Content-Type are HTTP headers. They are not JSON.
The JSON starts with the first { and this is the body of the POST. To create that body, you could use a C# object like:
public class MyJson {
public class MyRequest request {get ;set;}
}
public class MyRequest {
public string md5 {get;set;}
public string file_name {get;set;}
public string file_type {get;set;}
public List<string> features {get;set;}
public MyTe te {get;set;}
}
public class MyTe {
public List<string> reports {get;set;}
public List<MyImages> images {get;set;}
}
public class MyImages {
public string id {get;set;}
public int revision {get;set;}
}
And then use JsonConvert.SerializeObject on a MyJson object. To set the HTTP headers depends on what you're trying to do and with which tools, and that probably belongs in a different question.
EDIT: I said "and so on" because it's really just a rote exercise, and there are better tools to do this but I've updated.
Content-Disposition and Content-Type are request headers so they don't need to be in your json body
Here I've also demostrated how you can set a custom json property name using JsonProperty attribute.
static void Main(string[] args)
{
var myjason = new myJsonClass
{
Request = new requestClass
{
md5 = "da855ff838250f45d528a5a05692f14e",
file_name = "MyFile.docx",
file_type = "docx",
features = new[] { "te" },
te = new te
{
reports = new[] { "pdf", "xml" },
images = new a[] { new a { id = "7e6fe36e-889e-4c25-8704-56378f0830df", revision = 1 }, new a { id = "e50e99f3-5963-4573-af9e-e3f4750b55e2", revision = 1 } }
},
}
};
string json = JsonConvert.SerializeObject(myjason, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(json);
}
public class myJsonClass
{
[JsonProperty("request")]
public requestClass Request { get; set; }
}
public class requestClass
{
public string md5 { get; set; }
public string file_name { get; set; }
public string file_type { get; set; }
public string[] features { get; set; }
public te te { get; set; }
}
public class a
{
public string id { get; set; }
public int revision { get; set; }
}
public class te
{
public string[] reports { get; set; }
public a[] images { get; set; }
}
Output:
{
"request": {
"md5": "da855ff838250f45d528a5a05692f14e",
"file_name": "MyFile.docx",
"file_type": "docx",
"features": [
"te"
],
"te": {
"reports": [
"pdf",
"xml"
],
"images": [
{
"id": "7e6fe36e-889e-4c25-8704-56378f0830df",
"revision": 1
},
{
"id": "e50e99f3-5963-4573-af9e-e3f4750b55e2",
"revision": 1
}
]
}
}
}
I want to deserialise the following Json. I have tried the following:
JSON Data:
{
"data":[
{
"employee":[
{
"empdetails":[
{
"empid":"40",
"empname":"Amit",
"empdept":"Director",
"empphone":[
{
"home":"23432235",
"office":"2352353",
}]
},
{
"empid":"54",
"empname":"Abhishek",
"empdept":"HR",
"empphone":[
{
"home":"5445457",
"office":"34634634",
}]
},
{
"empid":"80",
"empname":"Rahul",
"empdept":"Finance"
},
{
"empid":"71",
"empname":"Anand",
"empdept":"Marketing",
"empphone":[
{
"home":"46346346",
"office":"346346346",
}]
}]
}],
}
Code:
using System;
using Newtonsoft.Json.linq;
using System.Collections.Generics;
class Program
{
public class emp
{
public int empid {get; set;}
public string empname {get; set;}
public string empdept {get; set;}
public string empcontact {get; set; }
}
static void main(string[] args)
{
WebClient c= new WebClient();
var json = c.DownloadString(new uri("sampleurl"));
dynamic dynamicObj=JsonConvert.DeserializeObject(json);
foreach (var data in dynamicObj.data)
{
foreach (var getempdet in data.employee)
{
foreach(var dat in getempdet)
{
foreach(var datas in dat)
{
foreach(var getempdetails in datas)
{
foreach(var finaldata in getempdetails)
{
Console.WriteLine("\t{0}", finaldata);
List<emp> empList=newList<emp>();
}
}
}
}
}
}
Console.ReadLine();
}
}
Create C# classes that map to your json. As below:
public class Data
{
public List<Employee> Employees { get; set; }
}
public class Employee
{
public List<EmpDetails> EmpDetailss { get; set; }
}
public class EmpDetails
{
public int Empid { get; set; }
public string Empname { get; set; }
public string Empdept { get; set; }
public EmpPhone EmpPhone{ get; set; }
}
public class EmpPhone
{
public string Home { get; set; }
public string Office { get; set; }
}
and then
WebClient c = new WebClient();
var json = c.DownloadString("sampleurl");
Data data = JsonConvert.DeserializeObject<Data>(json);