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
Related
I have a POCO like this:
public class Process
{
public Process() { }
[DataMember(Name = "lang_code")]
public string LCode { get; set; }
[DataMember(Name = "data_currency")]
public string Currency { get; set; }
[DataMember(Name = "country_code")]
public string CCode { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
Now when I serialize my POCO I get json back like this which has field name:
{"LCode":"en-US","Currency":"USD","CCode":"IN"}
Is there any way to get it the way DataMember fields are after serializing POCO. Something like below:
{"lang_code":"en-US","data_currency":"USD","country_code":"IN"}
Below is the code we have:
ProcessStr = ExtractHeader(headers, PROCESS_HEADER);
Console.WriteLine(ProcessStr);
if (!string.IsNullOrWhiteSpace(ProcessStr))
{
Process = DeserializeJson<Process>(ProcessStr);
if (Process != null && !string.IsNullOrWhiteSpace(Process.Gold))
{
Process.Gold = HttpUtility.HtmlEncode(Process.Gold);
}
ProcessStr = Process.ToString();
Console.WriteLine(ProcessStr);
}
private T DeserializeJson<T>(string str) where T : new()
{
try
{
return Utf8Json.JsonSerializer.Deserialize<T>(str);
}
catch (Exception e)
{
return new T();
}
}
It looks like you are using two different packages, Newtonsoft.Json to serialize and Utf8Json to deserialize. They use different annotations. You can get it to work, but it might be simpler to choose one or the other.
Newtonsoft.Json uses the JsonProperty attribute whereas Utf8Json uses the DataMember one.
using System;
using System.Diagnostics;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Utf8Json;
namespace JSONPropertyTest
{
public class Process
{
public Process() { }
[JsonProperty("lang_code")]
[DataMember(Name = "lang_code")]
public string LCode { get; set; }
[JsonProperty("data_currency")]
[DataMember(Name = "data_currency")]
public string Currency { get; set; }
[JsonProperty("country_code")]
[DataMember(Name = "country_code")]
public string CCode { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
class Program
{
static private T DeserializeJson<T>(string str) where T : new()
{
try
{
return Utf8Json.JsonSerializer.Deserialize<T>(str);
}
catch (Exception e)
{
return new T();
}
}
static void Main(string[] args)
{
var test = new Process { LCode = "en-US",Currency = "USD", CCode = "IN" };
var json = test.ToString();
Console.WriteLine($"serialized={test}");
var deserialized = DeserializeJson<Process>(json);
Debug.Assert(test.CCode == deserialized.CCode);
Debug.Assert(test.LCode == deserialized.LCode);
Debug.Assert(test.Currency == deserialized.Currency);
Console.WriteLine($"deserialized={deserialized}");
}
}
}
To just use Utf8Json you need to update your ToString method, which is the only one in the code you've shown that relies on Newtonsoft.Json. That would look like this:
public class Process
{
public Process() { }
[DataMember(Name = "lang_code")]
public string LCode { get; set; }
[DataMember(Name = "data_currency")]
public string Currency { get; set; }
[DataMember(Name = "country_code")]
public string CCode { get; set; }
public override string ToString()
{
return Utf8Json.JsonSerializer.ToJsonString(this);
}
}
{
"Global Quote": {
"01. symbol": "MSFT",
"02. latest trading day": "2018-11-19",
"03. previous close": "108.2900"}
}
This is the code I m using:
using (var reader = new StreamReader(response.GetResponseStream()))
{
JavaScriptSerializer js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
//This line is not working.
Stock stock = (Stock)js.Deserialize(objText, typeof(Stock));
return Ok(stock);
}
The stock is model as shown below:
public class Stock
{
public string symbol { get; set; }
public string latesttradingday { get; set; }
public string previousclose { get; set; }
}
All I m getting is Null in all field of Stock. What I m missing here? I m new to JSON.
Use JsonProperty
public class GlobalQuote
{
[JsonProperty("Global Quote")]
public Stock Stock { get; set; }
}
public class Stock
{
[JsonProperty("01. symbol")]
public string symbol { get; set; }
[JsonProperty("02. latest trading day")]
public string latesttradingday { get; set; }
[JsonProperty("03. previous close")]
public string previousclose { get; set; }
}
private static async Task Main(string[] args)
{
string test = #"{
""Global Quote"": {
""01. symbol"": ""MSFT"",
""02. latest trading day"": ""2018-11-19"",
""03. previous close"": ""108.2900""}
}";
var result = JsonConvert.DeserializeObject<GlobalQuote>(test);
}
Full Demo Here
Additional Resources
JsonProperty Class
Maps a JSON property to a .NET member or constructor parameter.
i have an application that has to deserialize an array of data wrapped in a "results" Root Object, using Netwonsoft.Json package from NuGet
The Json string is exactly this:
{"results":[{"Coin":"SBD","LP":0.000269,"PBV":-54.36,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true},{"Coin":"XMR","LP":0.027135,"PBV":11.44,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true}]}
This Json string is created from a Console App i made, i wanted it to look like this https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=BTC-NEO&tickInterval=hour
My class looks like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowsFormsApp2
{
public class Result
{
public string Coins { get; set; }
public decimal LastPrice { get; set; }
public decimal PercentBuyVolume { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
}
}
In the Main form i have a function to download from a URL that Json (i have XAMPP running Apache) and deserialize it in an array. And it looks like this:
private void DownloadBittrexData()
{
int PanelID = 0;
var Coin = new List<string>();
var LastPrice = new List<decimal>();
var PercentBuyVolume = new List<decimal>();
var MACD1M = new List<bool>();
var MACD30M = new List<bool>();
var MACD1H = new List<bool>();
var MACD1D = new List<bool>();
var client = new WebClient();
var URL = client.DownloadString("http://localhost/test.json");
Console.WriteLine("Json String from URL: " + URL);
var dataDeserialized = JsonConvert.DeserializeObject<RootObject>(URL);
foreach (var data in dataDeserialized.results)
{
Coin.Add(data.Coins);
LastPrice.Add(data.LastPrice);
PercentBuyVolume.Add(data.PercentBuyVolume);
}
int sizeOfArrayClose = Coin.Count - 1;
for (int i = 0; i <= sizeOfArrayClose; i++)
{
Console.WriteLine("Coin: " + Coin[i]);
Console.WriteLine("Lastprice: " + LastPrice[i]);
Console.WriteLine("PBV: " + PercentBuyVolume[i]);
}
}
Newtonsoft.Json is of course declared at the beginning of the form together with System.Net
using System.Net;
using Newtonsoft.Json;
The output looks like this:
Json String from URL: {"results":[{"Coin":"SBD","LP":0.000269,"PBV":-54.36,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true},{"Coin":"XMR","LP":0.027135,"PBV":11.44,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true}]}
Coin:
Lastprice: 0
PBV: 0
Coin:
Lastprice: 0
PBV: 0
It's like it fails to deserialize it after downloading it.
What should i do? Thank you very much.
Your property names don't map to the field names in the JSON. You could rename your C# properties to match the JSON, but it would make for unreadable downstream code.
Instead, you should map your properties (with nice, readable names) to the names that appear in the JSON, using JsonPropertyAttribute:
public class Result
{
public string Coin { get; set; } //didn't bother here: changed property name to Coin
[JsonProperty("LP")]
public decimal LastPrice { get; set; }
[JsonProperty("PBV")]
public decimal PercentBuyVolume { get; set; }
}
your model should be like this for deserialize json
public class Result
{
public string Coin { get; set; }
public double LP { get; set; }
public double PBV { get; set; }
public bool MACD1M { get; set; }
public bool MACD30M { get; set; }
public bool MACD1H { get; set; }
public bool MACD1D { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
}
LastPrice and PercentBuyVolume are not available in your model that's the reason it's getting an error.
I tried your exact code on my system and I was able to retrieve the result as expected. Hope this helps, It's easy to understand.
Here is the main class
static void Main(string[] args)
{
RootObject configfile = LoadJson();
foreach (var tResult in configfile.results)
{
Console.WriteLine("Coin: " + tResult.Coin);
Console.WriteLine("Lastprice: " + tResult.LP);
Console.WriteLine("PBV: " + tResult.PBV);
}
Console.ReadLine();
}
LoadJson Function would be
private static RootObject LoadJson()
{
string json = "{\"results\":[{\"Coin\":\"SBD\",\"LP\":0.000269,\"PBV\":-54.36,\"MACD1M\":true,\"MACD30M\":true,\"MACD1H\":true,\"MACD1D\":true},{\"Coin\":\"XMR\",\"LP\":0.027135,\"PBV\":11.44,\"MACD1M\":true,\"MACD30M\":true,\"MACD1H\":true,\"MACD1D\":true}]}";
RootObject configs = Deserialize<RootObject>(json);
return configs;
}
and Deserialize function would be
private static T Deserialize<T>(string json)
{
T unsecureResult;
string _DateTypeFormat = "yyyy-MM-dd HH:mm:ss";
DataContractJsonSerializerSettings serializerSettings = new DataContractJsonSerializerSettings();
DataContractJsonSerializer serializer;
MemoryStream ms;
unsecureResult = default(T);
serializerSettings.DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat(_DateTypeFormat);
serializer = new DataContractJsonSerializer(typeof(T));
ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
unsecureResult = (T)serializer.ReadObject(ms);
return unsecureResult;
}
and Now your Datamodel would be
public class Result
{
public string Coin { get; set; }
public double LP { get; set; }
public double PBV { get; set; }
public bool MACD1M { get; set; }
public bool MACD30M { get; set; }
public bool MACD1H { get; set; }
public bool MACD1D { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
}
i have the following class
using System;
public class AppEventsClass
{
public string title { get; set; }
public string description { get; set; }
}
after calling a remote webservice i retrive the following json string:
{"d":"[title\":\"test\",\"description\":\"test desc\"},{\"title\":\"test2\",\"description\":\"desc test 2\"}]"}
after retriving that json string, how can i convert the string in a List<> of AppEventsClass with Newtonsoft?
I tried several solutions, but nothing that works fine for me.
for example this:
List<AppEventsClass> result = new List<AppEventsClass>();
result = JsonConvert.DeserializeObject<List<AppEventsClass>>(content).ToList();
and this is the .asmx that serializes the string:
[ScriptMethod(UseHttpGet = true)]
public string GetEvents()
{
using (mySQLDataContext ctx = new secondosensoSQLDataContext())
{
List<eventi> eventiList = ctx.eventi.ToList();
List<AppEventsClass> eventiClassList = new List<AppEventsClass>();
for (int i = 0; i < eventiList.Count; i++)
{
AppEventsClass a = new AppEventsClass();
a.title = eventiList[i].titlolo_evento;
a.description = eventiList[i].descrizione_evento;
eventiClassList.Add(a);
}
var json = JsonConvert.SerializeObject(eventiClassList);
return json;
}
}
1st issues seems that the response we retrieve is not formed correctly
Assumed that the json string is looking like the following:
{"d":[{"title":"test","description":"test desc"},{"title":"test2","description":"desc test 2"}]}
The correct class for deserialization should look like this
public class Rootobject
{
public D[] d { get; set; }
}
public class D
{
public string title { get; set; }
public string description { get; set; }
}
Thanks
PS. Here is a working example:
class Program
{
static void Main(string[] args)
{
string json = "{\"d\":[{title:\"test\",description:\"test desc\"},{title:\"test2\",description:\"desc test 2\"}]}";
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(json);
}
}
public class Rootobject
{
public D[] d { get; set; }
}
public class D
{
public string title { get; set; }
public string description { get; set; }
}
My json response which i am generating from php :
{"name":"abhi","age":"20","id":"1"}
{"name":"abhi","age":"21","id":"4"}
And the c# code is:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Load(textBox1.Text);
}
public void Load(string keyword)
{
var client = new RestClient("http://localhost/query.php?name="+keyword);
var request = new RestRequest(Method.GET);
//request.AddParameter("name", keyword);
/*request.AddParameter("v", "1.0");
request.AddParameter("q", keyword);
request.AddParameter("hl", "id");
request.AddParameter("rsz", 5);*/
client.ExecuteAsync<RootObject>(request, (response) =>
{
// var resp = response.Data.ToString();
// var respLines = resp.Split('\n');
RootObject rootObject=response.Data;
listBox1.Items.Clear();
if (rootObject == null)
MessageBox.Show("null");
else
{
listBox1.Items.Add(rootObject.age+" " + rootObject.name);
}
});
}
}
}
public class RootObject
{
public string name { get; set; }
public string age { get; set; }
public string id { get; set; }
}
i am able to fetch the first row but not for multiple rows. Anyone has any idea how to fetch multiple rows in json format. How to create multiple objects of json and populate them?
That does not look like valid JSON, try returning a JSON array from PHP:
{
"rows": [
{"name":"abhi","age":"20","id":"1"},
{"name":"abhi","age":"21","id":"4"}
]
}
These would be the corresponding C# classes for deserialization:
public class Row
{
public string name { get; set; }
public string age { get; set; }
public string id { get; set; }
}
public class RootObject
{
public List<Row> rows { get; set; }
}
And you can add your rows with:
foreach (var row in rootOject.rows)
{
listBox1.Items.Add(row.age+" " + row.name);
}