I am trying to Deserialize a JSON api to c# on WP7. I need help in doing so. Im sure its an easy fix but i cannot just see it.
The JSON Data looks like this.
{
"chartDate" : 1349564400,
"retrieved" : 1349816722,
"entries" :
[
{
"position" : 1,
"previousPosition" : 0,
"noWeeks" : 1,
"artist" : "Rihanna",
"title" : "Diamonds",
"change" :
{
"direction" : "none",
"amount" : 0,
"actual" : 0
}
},
which translates to the following using http://json2csharp.com/
public class Change
{
public string direction { get; set; }
public int amount { get; set; }
public int actual { get; set; }
}
public class Entry
{
public int position { get; set; }
public int previousPosition { get; set; }
public int noWeeks { get; set; }
public string artist { get; set; }
public string title { get; set; }
public Change change { get; set; }
}
public class RootObject
{
public int chartDate { get; set; }
public int retrieved { get; set; }
public List<Entry> entries { get; set; }
}
In the application when i click the get feed button i am using the following code but it is coming back with the error Cannot Deserilize JSON object into type "System.Collections.Generic.List`1[Appname.RootObject
The following is my C# from Mainpage.cs
using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Reactive;
using Newtonsoft.Json;
namespace JsonDemo
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void Load_Click(object sender, RoutedEventArgs e)
{
var w = new SharpGIS.GZipWebClient();
Observable.FromEvent<DownloadStringCompletedEventArgs>(w, "DownloadStringCompleted")
.Subscribe(r =>
{
var deserialized = JsonConvert.DeserializeObject<List<RootObject>>(r.EventArgs.Result);
PhoneList.ItemsSource = deserialized;
});
w.DownloadStringAsync(new Uri("http://apiurl.co.uk/labs/json/"));
}
}
}
if r.EventArgs.Result returns the (correct) json in question, this should work:
var deserialized = JsonConvert.DeserializeObject<RootObject>(r.EventArgs.Result);
--EDIT--
string json = #"{
""chartDate"": 1349564400,
""retrieved"": 1349816722,
""entries"": [{
""position"": 1,
""previousPosition"": 0,
""noWeeks"": 1,
""artist"": ""Rihanna"",
""title"": ""Diamonds"",
""change"": {
""direction"": ""none"",
""amount"": 0,
""actual"": 0
}
}]
}";
var deserialized = JsonConvert.DeserializeObject<RootObject>(json);
Related
I have to pass following JSON format to the REST api.
"weconnect_validate":{
"Row":[
{"0":"44063fe6-fe22-11ea-bb30-005056923098::TEST10800::9888880470","1":"TEST10800"}
]
}
Now problem occurring here is that how i create class for
Row with variable name 0 and 1.
I have tried following
public class BasicRow
{
[JsonProperty("0")]
public string Zero { get; set; }
[JsonProperty("1")]
public string One { get; set; }
}
public class Weconnect_Validate
{
public BasicRow[] rows { get; set; }
}
but it is not working. In debug mode it is passing
Row:[{"Zero":......
Please suggest some tricks or different way to create c# class.
Edit
Following json object i need to send to REST api using http client .
{"PWSESSIONRS":{"PWPROCESSRS":{"PWDATA":{"weconnect_validate":{"Row":[{"0":"dc9a2d38-fe28-11ea-bb30-005056923098","1":"TEST10800"}]}},"PWHEADER":{"LOGIN_ID":"TEST10800","ORG_ID":"HSA","APP_ID":"HSA","IN_PROCESS_ID":"1","OUT_PROCESS_ID":"weconnect_validate"}}}}
My question is how to build c# classes for this type of json string or object.
QuickType.io suggested this, which is what my first thought was (Array of Dictionary<string, string>) given that your assertion that JsonProperty wasn't working:
namespace SomeNamespaceHere
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class RootClassNameHere
{
[JsonProperty("weconnect_validate")]
public WeconnectValidate WeconnectValidate { get; set; }
}
public partial class WeconnectValidate
{
[JsonProperty("Row")]
public Dictionary<string, string>[] Row { get; set; }
}
public partial class RootClassNameHere
{
public static RootClassNameHere FromJson(string json) => JsonConvert.DeserializeObject<RootClassNameHere>(json, SomeNamespaceHere.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this RootClassNameHere self) => JsonConvert.SerializeObject(self, SomeNamespaceHere.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
But I didn't actually encounter any problems using your proposed route:
with this code:
public class Row
{
[JsonProperty("0")]
public string Zero { get; set; }
[JsonProperty("1")]
public string One { get; set; }
}
public class WeconnectValidate
{
public List<Row> Row { get; set; }
}
public class Root
{
[JsonProperty("weconnect_validate")]
public WeconnectValidate WeconnectValidate { get; set; }
}
Used like:
var x = JsonConvert.SerializeObject(new Root()
{
WeconnectValidate = new WeconnectValidate()
{
Row = new List<Row>(){
new Row() { Zero = "a", One = "b" },
new Row() { Zero = "c", One = "d" }
}
}
});
With the latest Newtonsoft.Json
Good day, I just can't seem to wrap on this, I have this JSON document in mind, but how can I do it as a class?
the JSON goes like this :
{
"name": "stacking",
"id": "12345",
"moreDetails" : {
"new_item_0" : {
"id": "abcdefg"
},
"new_item_1" : {
"id": "hujklmn"
},
"new_item_n" : {
"id": "opqrtsu"
}
}
}
Where "moreDetails" have an infinite amount of "new_item_n" in it.
Gonna use this class as a format of my database in MongoDB.
The class I have in mind goes like this:
public string name;
public string id;
// beyond here I have no idea
You can use Dictionary<string, class>:
public partial class Root
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("moreDetails")]
public Dictionary<string, Item> MoreDetails { get; set; }
}
public class Item
{
[JsonProperty("id")]
public string Id { get; set; }
}
So this:
var x = new Root
{
Name = "stacking",
Id = "1",
MoreDetails = new Dictionary<string, Item> {
{"new_item_0", new Item {Id = "itemId"}}
}
};
JsonConvert.SerializeObject(x, Newtonsoft.Json.Formatting.Indented);
results in:
{
"name": "stacking",
"id": "1",
"moreDetails": {
"new_item_0": {
"id": "itemId"
}
}
}
Try using KeyValuePair where ObjectType is the class that describes the object behind your new_item_n
List<KeyValuePair<string,ObjectType>>
Or use the dictionary as the answer of Guru Strom!
Well since MovieDetails will be an infinite and dynamic it should be a dictionary. So something like this:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace Scratch
{
class Program
{
class Thing
{
public string Name { get; set; }
public string Id { get; set; }
public Dictionary<string, Item> MoreDetails { get; set; }
}
class Item
{
public string Id { get; set; }
}
static void Main(string[] args)
{
var json = File.ReadAllText("f.json");
var thing = JsonConvert.DeserializeObject<Thing>(json);
Console.WriteLine(thing.Name);
}
}
}
I have JSON like this
{
"amounts": [
{
"tid": 7072,
"amount": 10000,
"currency": "USD"
},
{
"tid": 7072,
"amount": 4000,
"currency": "USD"
}
],
"status": 0,
"errorCode": 0
}
I need to retrieve amount value from this JSON and to divide for example in 10. After that i would like to replace amount value in original json . How can i do this? I am using .Net json tools like NEwtonsoft json.
private string DivideAmounts(string str, int denominator)
{
var obj = (JObject)JsonConvert.DeserializeObject(str);
foreach (var amount in obj["amounts"])
{
var value = amount.Value<int>("amount");
var newValue = value / denominator;
amount["amount"] = newValue;
}
return obj.ToString();
}
Using Newtonsoft.Json.
Add check of argument "denominator" to avoid divide-by-zero error.
Use the following tool to generate classes:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp11
{
class Program
{
static void Main(string[] args)
{
var js = "{\"amounts\": [ { \"tid\": 7072, \"amount\": 10000, \"currency\": \"USD\" }, { \"tid\": 7072, \"amount\": 4000, \"currency\": \"USD\" } ], \"status\": 0, \"errorCode\": 0}";
var obj = Welcome.FromJson(js);
for (int i = 0; i < obj.Amounts.Length; i++)
{
obj.Amounts[i].AmountAmount /= 10;
}
var newjs = Serialize.ToJson(obj);
Console.WriteLine(newjs);
Console.ReadKey();
}
}
public partial class Welcome
{
[JsonProperty("amounts")]
public Amount[] Amounts { get; set; }
[JsonProperty("status")]
public long Status { get; set; }
[JsonProperty("errorCode")]
public long ErrorCode { get; set; }
}
public partial class Amount
{
[JsonProperty("tid")]
public long Tid { get; set; }
[JsonProperty("amount")]
public long AmountAmount { get; set; }
[JsonProperty("currency")]
public string Currency { get; set; }
}
public partial class Welcome
{
public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, Converter.Settings);
}
public static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
public static class Serialize
{
public static string ToJson(this Welcome self)
{
return JsonConvert.SerializeObject(self, Converter.Settings);
}
}
}
Generate quicktype from json2csharp like
public class Amount
{
public int tid { get; set; }
public int amount { get; set; }
public string currency { get; set; }
}
public class RootObject
{
public List<Amount> amounts { get; set; }
public int status { get; set; }
public int errorCode { get; set; }
}
1) First of all deserialize your json string to RootObject
2) Iterate over on amounts property in RootObject.
3) Make arithmetic operation on your amount like divide by 10.
4) Serialize again your RootObject.
Here I create a console app for your demonstration purpose that shows how above steps will be executed.
class Program
{
static void Main(string[] args)
{
string inputJson = #"{'amounts':[{'tid':7072,'amount':10000,'currency':'USD'},{'tid':7072,'amount':4000,'currency':'USD'}],'status':0,'errorCode':0}";
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(inputJson);
foreach (var item in rootObject.amounts)
{
item.amount = item.amount / 10;
}
//OR you can do it with shorter version of foreach
//rootObject.amounts.ForEach(x => x.amount = x.amount / 10);
string outputJson = JsonConvert.SerializeObject(rootObject);
Console.WriteLine(outputJson);
Console.ReadLine();
}
}
Output:
So i have some Json:
{
"name": "Shadow Realm",
"description": "A spooky Haloween inspired map",
"map": {
"version": 79,
"color_palette": [
{
"r": 96,
"g": 209,
"b": 234,
"a": 255
},
{
"r": 255,
"g": 55,
"b": 55,
"a": 255
}]
}
}
And i am am able to read the first few values however i am not able to read the version and i am not sure what i should be reading the map entry as, any ideas?
I would prefer not to have to use a plugin as i wish to keep the project as small as possible if its do-able.
using UnityEngine;
using System.Collections;
using System.Reflection;
using System.Linq;
using System;
[System.Serializable]
public class Tests : MonoBehaviour
{
private string jsonMapData;
void Start()
{
jsonMapData = Import_bnl_bin.LoadResourceTextfile("map.json");
MyClass jsonMap = new MyClass();
jsonMap = JsonUtility.FromJson<MyClass>(jsonMapData);
Debug.Log("Name " + jsonMap.name + " : Desc " + jsonMap.description + " : Version " + jsonMap.version);
}
public class MyClass
{
public string name;
public string description;
public int version;
}
}
Use http://json2csharp.com I generated the following classes using your sample JSON document.
public class ColorPalette
{
public int r { get; set; }
public int g { get; set; }
public int b { get; set; }
public int a { get; set; }
}
public class Map
{
public int version { get; set; }
public List<ColorPalette> color_palette { get; set; }
}
public class RootObject
{
public string name { get; set; }
public string description { get; set; }
public Map map { get; set; }
}
I'm not familiar with JsonUtility but my guess would be that you would replace this line:
jsonMap = JsonUtility.FromJson<MyClass>(jsonMapData);
With this:
jsonMap = JsonUtility.FromJson<RootObject>(jsonMapData);
Or you could rename RootObject to MyClass.
it seems that the classes needed to be serializable
[Serializable]
public class Map
{
public int version;
public List<ColorPalette> color_palette;
}
otherwise it fails to read the data, also i ended up removing the
{ get; set; }
as it was overriding the
.FromJson()
funtion and causing it to return null
I have my own code here and already get the JSON result then I haven't idea to move the JSON result into the interface (IEntities function) list below.
class GetCategory : IEntities
{
private JsonHandle _jsonhandle;
private string _ocategory;
public async void TaskCategory()
{
_jsonhandle = new JsonHandle();
_jsonhandle.StrAPI = "http://api.nytimes.com/svc/books/v3/lists/names.json?api-key=7bb034b7693d6f9753b2f68e00b98c78%3A16%3A73599437";
var client = new HttpClient();
Task<string> datatask = client.GetStringAsync(_jsonhandle.StrAPI);
try
{
var JsonRead = await datatask;
JObject oCategory = JObject.Parse(JsonRead);
List<JToken> results = oCategory["results"].Children().ToList();
//serialize JSON results into .NET objects
List<object> dtCategory = new List<object>();
foreach (JToken result in results)
{
object _dtcategory = JsonConvert.DeserializeObject<object>(result.ToString());
dtCategory.Add(_dtcategory);
var listname = result["list_name"];
}
}
catch (Exception error)
{
Console.WriteLine("AW!" + error.StackTrace);
}
public List<object> BookCategory()
{
}
}
In the last function that in IEntities interface, I need to put my JSON result in interface List<object>.
When working with JSON, the first thing to do is creating a model object. In order to this, either you should analyze JSON output manually, or you can generate the model automatically by going to the following link and pasting either the JSON your are going to use or the service link;
json2csharp.com
I've just used your API link and the output generated is;
public class Result
{
public string list_name { get; set; }
public string display_name { get; set; }
public string list_name_encoded { get; set; }
public string oldest_published_date { get; set; }
public string newest_published_date { get; set; }
public string updated { get; set; }
}
public class RootObject
{
public string status { get; set; }
public string copyright { get; set; }
public int num_results { get; set; }
public List<Result> results { get; set; }
}
This will be our model.
Secondly, as far as I can see, what you want to do is only to get the result list, thus, as you deserialize the JSON output, you are going to use the Model.Result and move them into a list.
Then, to get the response, a private method can be used which that returns an async Task<string>, and on the BookCategory() method, you can get the Results and deserialize JSON and initialize a list based on your JSON object model;
public List<Model.Result> BookCategory()
{
List<Model.Result> list = new List<Model.Result>();
var model = JsonConvert.DeserializeObject<Model.RootObject>(TaskCategory().Result);
list = model.results;
return list;
}
Deserializing JSON is as simply as below;
var model = JsonConvert.DeserializeObject<Model.RootObject>(TaskCategory().Result);
Model.cs
using System.Collections.Generic;
namespace SO1
{
public class Model
{
public class Result
{
public string list_name { get; set; }
public string display_name { get; set; }
public string list_name_encoded { get; set; }
public string oldest_published_date { get; set; }
public string newest_published_date { get; set; }
public string updated { get; set; }
}
public class RootObject
{
public string status { get; set; }
public string copyright { get; set; }
public int num_results { get; set; }
public List<Result> results { get; set; }
}
}
}
GetCategory.cs
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net.Http;
using System;
namespace SO1
{
public class GetCategory : IEntities
{
private String BaseUri;
public GetCategory(string BaseUri)
{
this.BaseUri = BaseUri;
}
private async Task<string> TaskCategory()
{
var httpClient = new HttpClient();
var parameters = new Dictionary<string, string>();
parameters["text"] = "text";
var response = await httpClient.GetStringAsync(BaseUri);
return response;
}
public List<Model.Result> BookCategory()
{
List<Model.Result> list = new List<Model.Result>();
var model = JsonConvert.DeserializeObject<Model.RootObject>(TaskCategory().Result);
list = model.results;
return list;
}
}
}
IEntities
using System.Collections.Generic;
namespace SO1
{
public interface IEntities
{
List<Model.Result> BookCategory();
}
}
Program.cs
using System;
using System.Collections.Generic;
namespace SO1
{
class Program
{
static void Main(string[] args)
{
string BaseUri = "http://api.nytimes.com/svc/books/v3/lists/names.json?api-key=7bb034b7693d6f9753b2f68e00b98c78%3A16%3A73599437";
IEntities entity = new GetCategory(BaseUri);
List<Model.Result> listBookCategory = new List<Model.Result>();
listBookCategory = entity.BookCategory();
foreach (Model.Result r in listBookCategory)
{
Console.WriteLine();
Console.WriteLine("...List Name : " + r.list_name);
Console.WriteLine("...Display Name : " + r.display_name);
Console.WriteLine("...List Name Encoded : " + r.list_name_encoded);
Console.WriteLine("...Oldest Published Date : " + r.oldest_published_date);
Console.WriteLine("...Oldest Published Date : " + r.newest_published_date);
Console.WriteLine("...Updated : " + r.updated);
Console.WriteLine();
}
}
}
}
Output (only first three results printed)
...List Name : Combined Print and E-Book Fiction
...Display Name : Combined Print & E-Book Fiction
...List Name Encoded : combined-print-and-e-book-fiction
...Oldest Published Date : 2011-02-13
...Oldest Published Date : 2015-12-27
...Updated : WEEKLY
...List Name : Combined Print and E-Book Nonfiction
...Display Name : Combined Print & E-Book Nonfiction
...List Name Encoded : combined-print-and-e-book-nonfiction
...Oldest Published Date : 2011-02-13
...Oldest Published Date : 2015-12-27
...Updated : WEEKLY
...List Name : Hardcover Fiction
...Display Name : Hardcover Fiction
...List Name Encoded : hardcover-fiction
...Oldest Published Date : 2008-06-08
...Oldest Published Date : 2015-12-27
...Updated : WEEKLY