I want to write a json file from C# code as following json file would look:
{
"Monday": [
{
"class": "Example",
"time": "09:00"
},
{
"class": "Example2",
"time": "09:50"
}
],
"Tuesday": [
{
"class": "Example3",
"time": "09:00"
},
{
"class": "Example4",
"time": "09:50"
}
]
}
EDIT This is the class i'm using:
public class Lesson {
public string title { get; set; }
public string timeStart { get; set; }
public string timeEnd { get; set; }
}
I've found ways to write the single objects into the file, although I've found nothing about the arrays.
Excuse me in advance if the solution is obvious and I'm wasting your time, but I just recently started working with json files.
Thanks in advance,
bezunyl
You could:
add Json.NET to your project
create Dictionary<string,List<Lesson>>
Call JsonConver.SerializeObject(dict).
Here is an example of many possible ways how to interact with the dictionary.
dict["Monday"]= new List<Lesson>();
dict["Monday"].Add(new Lesson(...));
When calling SerializeObject you can specify formatting as Indented: `JsonConvert.SerializeObject(o, Formatting.Indented);`
Related
I'm trying to deserialize json-formatted response below.
{
"context": "xxxxxx"
"value": [
{
"Id": "123"
"Time": "2022-12-01"
}
{
"Id": "123"
"Time": "2022-12-01"
}
....
]
}
According to this: https://www.newtonsoft.com/json/help/html/deserializeobject.htm, this code should work.
public class WorkingSetContent
{
/// <summary>Collection ID</summary>
[JsonProperty("context")]
public string Context { get; set; }
/// <summary>UserRelationship</summary>
[JsonProperty("value")]
public IList<ItemClass> Items { get; set; }
}
But I'm getting a build error : "Change 'Items' to be read-only by removing the property setter."
I changed the setter to private to avoid this build error, then I was able to run it, but it causes a runtime error as null value is passed.
This is the code analysis rule you're running up against.
One option is to initialize your collection property with an empty list:
[JsonProperty("value")]
public IList<ItemClass> Items { get; } = new List<ItemClass>();
However, the code analysis rule explicitly says:
You can suppress the warning if the property is part of a Data Transfer Object (DTO) class.
Since you're deserializing this class from JSON, I think it's safe to assume it's a DTO. I would recommend using a pattern in your .globalconfig or .editorconfig files to suppress this rule for all of your DTO model classes.
You have to fix your json
{
"context": "xxxxxx",
"value": [
{
"Id": "123",
"Time": "2022-12-01"
},
{
"Id": "123",
"Time": "2022-12-01"
}
]
}
I have a json file and I deserialised it as shown in the code below. Some context, dex is a robot and it has information such as battery and so on as shown in the json file below. I want to read the battery status for the robot that the user selected ( robot).
This is my code, currently im only accessing data.dex but i want to change it to whichever data.robot, where robot is a variable
var data = JsonConvert.DeserializeObject<Root>(json);
var robot = queryDetails2.Amr;
var text =$"";
if (data.dex.battery.status == "good")
{
text = $"{queryDetails2.Amr}'s battery is in good condition. ";
}
This is the json file:
{
"dex":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
},
"dex_1":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
},
"dex_2":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
}
}
I wanted to use the GetMethod or the solution as suggested in this question (https://stackoverflow.com/questions/53076743/how-to-access-variable-of-a-nested-functions-in-python[1]).
However, im getting errors like it does not have a method. Now im confused, was it because i used var? but the deserialised method converts the json to an object though..
Anyway, how should i approach this?
Assuming that you have 3 robots with different names: dex, dex_1 and dex_2, you should reorganize your solution to treat the json data as a list of Robots instead of 3 separate variables for each robot.
To do this, first your json should look like this:
{
"robots":[
{
"name":"dex",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
},
{
"name":"dex_1",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
},
{
"name":"dex_2",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
}]
}
Next, update your serialization classes. Add a field called name in the Robot class or whatever class type you currently have for data.dex. In Root, remove the "dex" fields and add a List<Robot>.
public class Root
{
public List<Robot> robots { get; set; }
}
public class Robot
{
public string name { get; set; }
public Job current_job { get; set;}
public Battery battery{ get; set; }
}
Now you can write whatever logic to get the right robot data. Here is an example using System.Linq:
var robotName = "dex_2";
var robotInfo = data.robots.First(x => x.name.Equals(robotName));
var text = $"{robotName}'s battery is in {robotInfo.battery.status} condition.";
{
"_id": "underscore",
"_rev": "136-824a0ef7436f808755f0712c3acc825f",
"name": "underscore",
"description": "JavaScript's functional programming helper library.",
"dist-tags": {},
"versions": {
"1.0.3": {
"name": "xxx",
"description": "xxx"
},
"1.0.4": {},
"1.1.0": {}
}
}
I would like to retrieve the latest version(1.1.0) from the json file. However, it always gives out me errors of "can not deserialize json object into type RootObject
Here is my class
public class versions
{
public string name { get; set; }
public string description { get; set; }
}
public class RootObject
{
public List<versions> vs { get; set; }
}
And here is where I used it
RootObject[] dataset = JsonConvert.DeserializeObject<RootObject[]>(json);
Any idea. Many thankx
Update:
I have updated the JSON file format, but some problem..
I think the problem is, that in JSON you have to quote all "field"/attribute names. (Thats a difference from standard Javascript-Notation, where you can have unquoted attributes).
So, your file should be like:
{
"_id" : "underscore",
"versions": {
"1.0.3" : {
"name": "xxx",
"description": "xxx"
}
}
Note that {1.0.3: { name: "xxx" } } wouldn't be valid JavaScript either since '1.0.3' is an invalid identifier in JavaScript.
Looking at the JSON in your updated answer:
{
"_id" : "underscore",
"versions": {
"1.0.3" : {
"name": "xxx",
"description": "xxx"
},
"1.0.4" : {
"name": "xxx",
"description": "xxx"
}
}
This is still Invalid JSON - you have 4 opening { and only 3 closing }
you should use http://jsonlint.com/ - to validate your JSON and ensure it is Valid
I've fixed your json in question. Now for your real question
I would like to retrieve the latest version(1.1.0) from the json file. However, it always gives out me errors of "can not deserialize json object into type RootObject
You have property names like 1.0.3 that are unknown at compile time. So you can not deserialize them to a concrete class. You should handle them dynamically.
Try this:
var versions = JObject.Parse(json)["versions"]
.Children()
.Cast<JProperty>()
.ToDictionary(c => c.Name, c => c.Value.ToObject<versions>());
Let's say this is a collection of 2 Bson documents
{
"_id": "...",
"name": "Test1",
"sub": {
"street": "134 Fake Street",
"city": "NoWhere"
}
},
{
"_id": "...",
"name": "Test2",
"sub": {
"height": "10",
"width": "20",
"sub2": {
"type": "something"
}
}
}
where the first level is a structured class but sub-levels can be completely unstructured and can have further nested documents several levels deep.
How can I deserialize this document to a C# class? All samples I have seen assume some structure in nested documents.
The following class gives an error:
public class Report
{
[BsonId]
public ObjectId _id { get; set; }
public string name { get; set; }
public BsonDocument sub { get; set; }
}
Type 'MongoDB.Bson.BsonString' with data contract name '...' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
EDIT
What I'm trying to do might be complete non-sense. Is it a better idea to just use one BsonDocument and handle everything manually without a structured class?
I don't think the error message you are getting is from the C# driver. Can you please provide a stack trace?
I've tried to reproduce your issue but it works fine with my test program. See:
http://pastie.org/5032283
The document inserted by the above test program looks like this:
> db.test.find()
{ "_id" : ObjectId("5075fc6ee447ad1354c1f018"), "name" : "John Doe", "sub" : { "x" : 1, "y" : 2 } }
>
I know this is not hard, but I've been staring at the JSON.Net documentation for a half hour and don't see how it works. I've got it setup, but my initial attempts are failing and the documenation that I have looked at so far isn't making it obvious (to me, at least) how to deserialize the array form response.data and then get at the individual fields of each record.
Also, I don't need to use JSON.Net - it just seemed like a good choice. Any solution will do just fine.
{
"request":{
"Format":"json",
"Target":"Affiliate",
"Method":"findAll",
"Service":"HasOffers",
"Version":"2",
"NetworkId":"directagents",
"NetworkToken":"......"
},
"response":{
"status":1,
"data":{
"2056":{
"Affiliate":{
"id":"2056",
"company":
"123 Greetings 123 Greetings (CD186)",
"address1":"1 Change Address",
"address2":"",
"city":"City",
"region":"NY",
"country":"US",
"other":null,
"zipcode":"11111",
"phone":"-",
"fax":null,
"website":null,
"signup_ip":null,
"date_added":"2012-02-24 18:00:24",
"modified":-62169966000,
"ref_id":"CD186",
"status":"pending",
"wants_alerts":"1",
"account_manager_id":"20",
"payment_method":"check",
"payment_terms":"net 30",
"w9_filed":"0",
"referral_id":null,
"affiliate_tier_id":null,
"fraud_activity_score":null,
"fraud_activity_alert_threshold":null,
"fraud_activity_block_threshold":null,
"fraud_profile_alert_threshold":null,
"fraud_profile_block_threshold":null,
"scrub_offer_pixels":null,
"shared":"0"
}
},
"1606":{
.......this is enough to see how its structured....
You could model that “array” as Dictionary<int, AffiliateHolder>. The classes for that JSON could look like this:
class Top
{
public Request Request { get; set; }
public Response Response { get; set; }
}
class Request
{
public string Format { get;set; }
// etc.
}
class Response
{
public int Status { get; set; }
public Dictionary<int, AffiliateHolder> Data { get; set; }
}
class AffiliateHolder
{
public Affiliate Affiliate { get; set; }
}
class Affiliate
{
public int Id { get; set; }
// etc.
}
var o = JsonConvert.DeserializeObject<Top>(myJSONString);
The fastest, easiest way is to use Json.NET and LINQ to Json. Given your example above, the following code:
var parsedJson = JObject.Parse(rawJson);
foreach (var item in parsedJson["response"]["data"])
{
Console.WriteLine(item.ToString());
}
would write out the following to the console:
"2056": {
"Affiliate": {
"id": "2056",
"company": "123 Greetings 123 Greetings (CD186)",
"address1": "1 Change Address",
"address2": "",
"city": "City",
"region": "NY",
"country": "US",
"other": null,
"zipcode": "11111",
"phone": "-",
"fax": null,
"website": null,
"signup_ip": null,
"date_added": "2012-02-24 18:00:24",
"modified": -62169966000,
"ref_id": "CD186",
"status": "pending",
"wants_alerts": "1",
"account_manager_id": "20",
"payment_method": "check",
"payment_terms": "net 30",
"w9_filed": "0",
"referral_id": null,
"affiliate_tier_id": null,
"fraud_activity_score": null,
"fraud_activity_alert_threshold": null,
"fraud_activity_block_threshold": null,
"fraud_profile_alert_threshold": null,
"fraud_profile_block_threshold": null,
"scrub_offer_pixels": null,
"shared": "0"
}
}
It is not necessary to create concrete classes for explicit deserialization. Obviously that is a perfectly valid approach, however, if that's your style preference.
See http://james.newtonking.com/projects/json/help/LINQtoJSON.html for more examples.
I think you can try creating a simple example, not a huge json like that one.
Take a look at http://servicestack.net/ it is an alternative to Json.NET, it is faster and the learning curve is small. You can find a lot of examples on the website.
Is this in javascript? You should be able to just do this:
JSON.parse(response.data)