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);
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'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());
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!
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.
I use JSON.NET and I would like to parse the following object which I get from a WebService. Can someone post an example on how to do that?
#"{""MessageType"":0,
""Message"":""Success"",
""Value"":[
{""listId"":1,
""listName"":""DemoList"",
""itemInList"":[
{
""fromDate"":""\/Date(1228946400000)\/"",
""fromLocation"":null,
""toLocation"":null,
""originalRequest"":""water"",
""creationDate"":""\/Date(1339448400000)\/"",
""typeId"":1
},
{
""fromDate"":null,
""fromLocation"":null,
""toLocation"":null,
""originalRequest"":""gala"",
""creationDate"":""\/Date(1304370000000)\/"",
""typeId"":1
}
]}
]}"
JSON Object
{
"MessageType":0,
"Message":"UserLists",
"Value":
[
{
"listId":1,
"listName":"DemoList",
"itemInList"
[
{
"fromDate":"\/Date(1228946400000)\/",
"fromLocation":null,
"toLocation":null,
"originalRequest":"water",
"creationDate":"\/Date(1339448400000)\/",
"typeId":1
},
{
"fromDate":null,
"fromLocation":null,
"toLocation":null,
"originalRequest":"gala",
"creationDate":"\/Date(1304370000000)\/",
"typeId":1
}
],
"numberOfItems":2
}
]
}
Thanks.
You need to create some entity like this:
public class Entity
{
public int MessageType { get; set; }
public string Message { get; set; }
public List<EntityValue> Value { get; set; }
}
public class EntityValue
{
public int listId { get; set; }
public string listName { get; set; }
public List<ItemInList> itemInList { get; set; }
}
public class ItemInList
{
public DateTime? fromDate { get; set; }
public string fromLocation { get; set; }
public string toLocation { get; set; }
public string originalRequest { get; set; }
public DateTime creationDate { get; set; }
public int typeId { get; set; }
}
The entity must has the same structure like the json data.
And you can call the Method:
JsonConvert.DeserializeObject<Entity>(json);
If it has any exception,you need to adjust the entities until it works.
Please read the below link for parsi in metro style application.
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh770287.aspx