I've got the following structure for a RavenDB document
{
"RpcTechDataCollectionModel": {
"Weekend": "March 16 - 17, 2013",
"ServiceTitle": "Some Title",
"Notes": "",
"WeekendServices": [{
"ServiceTime": "",
"SiteName": "Bowridge",
"SoundOperator": "Rob",
"WorshipLeader": "Daryl",
"Notes": "",
"Songs": [{
"SongName": "Foo",
"MinSpl": "86",
"MaxSpl": "92",
"Note": ""
}, {
"SongName": "Bar",
"MinSpl": "89",
"MaxSpl": "96",
"Note": ""
}]
}, {
"ServiceTime": "",
"SiteName": "Bearspaw",
"SoundOperator": "Peter",
"WorshipLeader": "Tim",
"Notes": "",
"Songs": [{
"SongName": "Das",
"MinSpl": "86",
"MaxSpl": "91",
"Note": ""
}, {
"SongName": "Bar",
"MinSpl": "87",
"MaxSpl": "99",
"Note": ""
}]
}]
}
}
Now I'm trying to build a model for this, but I'm wondering what the best way to structure it would be. Note, none of the sub-objects WeekendService or Song will be used outside of the parent object RpcTechCollectionModel
option one would be
namespace MyProject.Models {
using System.Collections.Generic;
public class RpcTechDataCollectionModel{
RpcTechDataCollectionModel(){
this.WeekendServices = new List<WeekendService>();
}
public string Weekend { get; set; }
public string ServiceTitle { get; set; }
public string Notes { get; set; }
public List<WeekendService> WeekendServices { get; set; }
public class WeekendService{
WeekendService(){
this.SongRecords = new List<SongRecord>();
}
public DateTime ServiceTime { get; set; }
public string SiteName { get; set; }
public string SoundOperator { get; set; }
public string WorshipLeader { get; set; }
public string Notes { get; set; }
public List<Song> Songs { get; set; }
public class Song {
public string SongName { get; set; }
public double MinSpl { get; set; }
public double MaxMax { get; set; }
public string Note { get; set; }
}
}
}
}
I prefer this as it is nice and clean, and easy to understand. The problem is that it technically violates the "One class per file" rule
option two
public class RpcTechDataCollectionModel{
RpcTechDataCollectionModel(){
this.WeekendServices = new List<WeekendService>();
}
public string Weekend { get; set; }
public string ServiceTitle { get; set; }
public string Notes { get; set; }
public List<WeekendService> WeekendServices { get; set; }
}
public class WeekendService{
WeekendService(){
this.SongRecords = new List<SongRecord>();
}
public DateTime ServiceTime { get; set; }
public string SiteName { get; set; }
public string SoundOperator { get; set; }
public string WorshipLeader { get; set; }
public string Notes { get; set; }
public List<Song> Songs { get; set; }
}
public class Song {
public string SongName { get; set; }
public double MinSpl { get; set; }
public double MaxMax { get; set; }
public string Note { get; set; }
}
This does not violate that rule, but seems like a bit of a pain.
What would be the pros/cons to doing it one way or the other, and is one way considered "right / prefered", or is it more "whatever floats your boat" in a situation like this?
Nested classes are usually used to hide implementation details, and thus prevent consumers from misusing them. As these classes just define data contracts, there seems to be nothing to hide. Even if you wanted to prevent anyone from modifying them (which makes sense for data contracts you keep ownership of), better make them sealed.
I would have them in different files and perhaps grouped in folder.
Related
I have the following JSON string
{
"data": [
{
"symbol": "1COV.GE",
"exposure": "0",
"makerExposure": "-2028",
"takerExposure": "2028",
"makerPnl": "447.6688",
"takerPnl": "-447.6688",
"makerPositions": [
{
"name": "IB_001",
"position": "-2028",
"vwap": "47.41",
"pnl": "447.6688"
}
],
"takerPositions": [
{
"name": "MT5_1",
"position": "2028",
"vwap": "47.41",
"pnl": "-447.6688"
}
]
},
{
"symbol": "A",
"exposure": "0",
"makerExposure": "-10",
"takerExposure": "10",
"makerPnl": "-4.6",
"takerPnl": "4.6",
"makerPositions": [
{
"name": "IB_002",
"position": "-10",
"vwap": "136.78",
"pnl": "-4.6"
}
],
"takerPositions": [
{
"name": "MT5_1",
"position": "10",
"vwap": "136.78",
"pnl": "4.6"
}
],
"total": 2
}
}
And my goal is to serialize it into a List of object from the NODE "Data":
I have the classes that map the data node fields:
public class Positions
{
public string name { get; set; }
public string position { get; set; }
public string vwap { get; set; }
public string pnl { get; set; }
}
public class ExPositions
{
public string symbol { get; set; }
public string exposure { get; set; }
public string makerExposure { get; set; }
public string takerExposure { get; set; }
public string makerPnl { get; set; }
public string takerPnl { get; set; }
public OZPositions makerPositions { get; set; }
public OZPositions takerPositions { get; set; }
}
Do you have any ideas how I can convert the node "data" to list of "ExPositions" objects, eg. List
I've did this but so far it throws an error
var positions = JsonSerializer.Deserialize<ExPositions>(json_string);
There is an error in your json - it's missing a closing ] for the array (I'll assume it's a typo).
The real problem is that you need a wrapper class to represent the data node of the json which should contain a list (or array) of ExPositions. The makerPositions and takerPositions should also become lists (or arrays) too. Add the following class and update the position properties of ExPositions:
public class Data
{
public List<ExPositions> data { get; set; }
}
// change positions to use a List too
public class ExPositions
{
...
public List<Positions> makerPositions { get; set; }
public List<Positions> takerPositions { get; set; }
}
Then you can deserialize using:
var result = JsonSerializer.Deserialize<Data>(json);
It's not clear where the ""total"": 2 property should be in your models (it's not clear in the json because of the issue I mentioned), you could add it to the Data class above (if it belongs there).
Online demo
Try with:
public class Positions
{
public string name { get; set; }
public string position { get; set; }
public string vwap { get; set; }
public string pnl { get; set; }
}
public class ExPositions
{
public string symbol { get; set; }
public string exposure { get; set; }
public string makerExposure { get; set; }
public string takerExposure { get; set; }
public string makerPnl { get; set; }
public string takerPnl { get; set; }
public Positions makerPositions { get; set; }
public Positions takerPositions { get; set; }
}
public class YourResult{
public ExPositions data { get; set; }
public int total { get; set; }
}
And then call:
var positions = JsonSerializer.Deserialize<YourResult>(json_string);
As haldo mentioned, there is a typo in your JSON. To quickly parse and validate your JSON data, you can use any online JSON parsers to validate your JSON data. I usually use the chrome extension JSON Viewer Pro.
Also, in the link that haldo provided to the .NET Fiddle for the demo, there is a trailing comma in JSON data which JSON deserializers might not ignore.
Here is the link to the edited demo that haldo provided.
Edited Demo
I have the following json
{
"android_play_store_link": "xyz",
"ios_app_store_link": "",
"sticker_packs": [
{
"identifier": "1",
"name": "abc",
"publisher": "Jane Doe",
"tray_image_file": "xyz.png",
"image_data_version":"1",
"avoid_cache":false,
"publisher_email":"",
"publisher_website": "",
"privacy_policy_website": "",
"license_agreement_website": "",
"stickers": [
{
"image_file": "abc.webp",
"emojis": ["☕","🙂"]
},
{
"image_file": "cdf.webp",
"emojis": ["😩","😰"]
},
{
"image_file": "efg.webp",
"emojis": ["☕","🙂"]
}
]
}
]
}
I have no acquaintance with json until now, How can i deserialize this ?
I know how to do the basic read and write code from persistent data path of unity. But how do i process this json ?
My main goal is as the player wins a level, a new key and value would be added to the "stickers" attribute, Also after some levels I want to add changes to the sticker packs attribute later.
Plus how will i modify the value of image data version in a specific sticker pack item ?
Thanks in advance
you can use Newtonsoft.Json library to deserialize and serialize. Find below the respective C# class.
public class Sticker
{
public string image_file { get; set; }
public IList<string> emojis { get; set; }
}
public class StickerPack
{
public string identifier { get; set; }
public string name { get; set; }
public string publisher { get; set; }
public string tray_image_file { get; set; }
public string image_data_version { get; set; }
public bool avoid_cache { get; set; }
public string publisher_email { get; set; }
public string publisher_website { get; set; }
public string privacy_policy_website { get; set; }
public string license_agreement_website { get; set; }
public IList<Sticker> stickers { get; set; }
}
public class Root
{
public string android_play_store_link { get; set; }
public string ios_app_store_link { get; set; }
public IList<StickerPack> sticker_packs { get; set; }
}
Code to Deserialize:
Root root = JsonConvert.DeserializeObject<Root>(json);
I know people asked and already got some answers very similar question before like this, but still, I couldn't figure it out about mine. I have a JSON file contains a multidimensional object, like below:
{
"Common": {
"Required": "Required Entry ",
"Photos": "Photos",
"Videos": "Videos",
"Register": "Register"
},
"Forms": {
"Form": "Forms",
"Name": "Name",
"Phone": "Phone",
"Email": "Email",
"Message": "Message"
},
"Sections": {
"Home": {
"EventDateTime": "",
"MainTitle": "",
"SubTitle": ""
},
"About": {},
"Venue": {},
"Schedule": {},
"Speakers": {},
"Sponsors": {},
"Price": {},
"Contact": {}
}
}
I would like to deserialize it into my view model (LanguagesViewModel) like this:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class LanguagesViewModel
{
public Common Common { get; set; }
public Buttons Buttons { get; set; }
public Forms Forms { get; set; }
public Navbar Navbar { get; set; }
public Sections Sections { get; set; }
}
public class Common
{
public string Required { get; set; }
public string Photos { get; set; }
public string Videos { get; set; }
public string Register { get; set; }
}
public class Forms
{
public string Form { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Message { get; set; }
}
public class Sections
{
public Home Home { get; set; }
public About About { get; set; }
public Venue Venue { get; set; }
public Schedule Schedule { get; set; }
public Speakers Speakers { get; set; }
public Sponsors Sponsors { get; set; }
public Price Price { get; set; }
public Contact Contact { get; set; }
}
public class Home
{
public string EventDateTime { get; set; }
public string MainTitle { get; set; }
public string SubTitle { get; set; }
}
public class About
{
}
public class Venue
{
}
public class Schedule
{
}
public class Speakers
{
}
public class Sponsors
{
}
public class Price
{
}
public class Contact
{
}
}
Some of the snippet to do this:
using (StreamReader sr = new StreamReader(language_file_path))
{
string contents = sr.ReadToEnd();
items = JsonConvert.DeserializeObject<LanguagesViewModel>(contents);
}
Somehow, I only can get the first level of the objects, which is:
LanguagesViewModel{
Common:null,
Forms:null,
Sections:null
}
Not the second level, not the third level. Did I do something wrong or have I missed something? Very appreciated for any kind of help.
Thank you.
You can Use this static class
public static class JsonHelper
{
public static T ToObject<T>(this string content)
{
var obj = JObject.Parse(content).GetValue(typeof(T).Name);
if (obj == null)
throw new NullReferenceException();
else
return obj.ToObject<T>();
//This ToObject here is default method written in object
}
}
Usage
var mymodel= json.ToObject<Forms>();
Or create a JSON object and read it with magic strings.
//Creating your JSON object
JObject content = JObject.Parse(sr.ReadToEnd()//or your json);
//content["your object name"] let you access to you object
var common =(Common)content["Common"];
in multidimensional objects, you can access them like this.
//content["level1"]["level2"]["level3"] & ...
var sections= (Home)content["Sections"]["Home"];
Also this way may work but i prefer the way with magic strings.
dynamic jsonObject = new JObject.Parse(sr.ReadToEnd());
var common = jsonObject.Common;
You can find more in this link
I hope this Helps!
Sorry for the very ambiguous title but I don't quite know the question I am asking and have spent a couple of hours reading questions on here and am none the wiser!
I have a json array which looks like this:
{
"terms": "http://www.xe.com/legal/dfs.php",
"privacy": "http://www.xe.com/privacy.php",
"from": "USD",
"amount": 1,
"timestamp": "2018-08-14T00:00:00Z",
"to": [
{
"quotecurrency": "EUR",
"mid": 0.8771637444
},
{
"quotecurrency": "GBP",
"mid": 0.7835914281
}
]
}
My code looks like this:
public class DeserializeEX
{
//public string Disclaimer { get; set; }
//public string License { get; set; }
public string Timestamp { get; set; }
public string From { get; set; }
public DeserializeEXto To;
}
public class DeserializeEXto
{
public Dictionary<string, double> To { get; set; }
}
The bit I can't work out now is how to access that dictionary when deserializing?
This obviously doesn't work because result4.To isn't the correct thing to look at:
var result4 = JsonConvert.DeserializeObject<DeserializeEX>(response);
foreach (KeyValuePair<string, double> entry4 in result4.To)
{
outputData.Rows.Add(result4.Timestamp, loadBaseCurr, entry4.Key, entry4.Value);
}
Your DeserializeEXto class is wrong, it should really look like this:
public class DeserializeEXto
{
public string QuoteCurrency { get; set; }
public double Mid { get; set; }
}
And the To property in the root class needs to be this:
public IEnumerable<DeserializeEXto> To { get; set; }
And now your loop will look something like this:
foreach (var entry4 in result4.To)
{
outputData.Rows.Add(result4.Timestamp, loadBaseCurr, entry4.QuoteCurrency, entry4.Mid);
}
I don't think your model matches your json. Main issue is that for your to, it's actually an object array, instead of a dictionary.
Try this model:
public class CurrencyDTO
{
public string Terms { get; set; }
public string Privacy { get; set; }
public string From { get; set; }
public double Amount { get; set; }
public DateTimeOffset Timestamp { get; set; }
public List<QuoteCurrencyDTO> To { get; set; }
}
public class QuoteCurrencyDTO
{
public string QuoteCurrency { get; set; }
public double Mid { get; set; }
}
I have the simple JSON:
[
{
"new_as_cod": "0010955",
"as_nome": "NAME",
"as_cpf": "1212121212",
"as_email": "IM#UOL.COM.BR",
"as_cep": "88.025-200",
"igr_nome": "1\u00aa IGREJA BATISTA - FLORIANOPOLIS",
"id": "2781",
"valor": "50.00",
"pg_tipo_id": "CC",
"status": "Ativo",
"idstatus": "1"
}
]
... and a C# class generated from here:
public class RootObject
{
public string new_as_cod { get; set; }
public string as_nome { get; set; }
public string as_cpf { get; set; }
public string as_email { get; set; }
public string as_cep { get; set; }
public string igr_nome { get; set; }
public string id { get; set; }
public string valor { get; set; }
public string pg_tipo_id { get; set; }
public string status { get; set; }
public string idstatus { get; set; }
}
I have tried this:
RootObject data = JsonConvert.DeserializeObject<RootObject>(stringdate);
But I get the error:
How can I solve it?
[{ "new_as_cod": "0010955", "as_nome": "NAME", "as_cpf": "1212121212", "as_email": "IM#UOL.COM.BR", "as_cep": "88.025-200", "igr_nome": "1\u00aa IGREJA BATISTA - FLORIANOPOLIS", "id": "2781", "valor": "50.00", "pg_tipo_id": "CC", "status": "Ativo", "idstatus": "1" }]
If it has [] this is a collection.
Try this.
JsonConvert.DeserializeObject<List<RootObject>>(stringdate);
Yes, this JSON is a collection, so the variable needs to be list too.
List<RootObject> data = JsonConvert.DeserializeObject<List<RootObject>>(stringdate);