RESTful service and JSON array - c#

I have a .NET Core 1.x Web API project and I am trying to accept an array on HTTP post, but I have been unable to get this working. I have validated the following JSON
{
"LogEntry": [{
"a": 1238976,
"b": "test",
"c": "sub test",
"d": "some syb system comp",
"e": 1234,
"f": "my category",
"g": "my event name",
"h": "my sub event",
"i": "user def 1",
"j": "7/22/2008 12:11:04 PM",
"k": 45,
"l": 65,
"n": "Chris",
"o": "C:\\temp\\",
"p": 1234567890,
"q": 84,
"r": "eeeee stuff",
"s": "ddddd stuff",
"t": 90210
}]
}
I have a model class so I need each array item to be added to a list of the model type. This is where I am stuck. I have only been able to get this working with a single entry not in an array. My C# for that scenario is:
[HttpPost]
public string Post([FromBody] JObject test)
{
var result = JsonConvert.DeserializeObject<EventManagerLogEntry>(test.ToString());
return "wootwoot";
}
Any direction on how I can loop through each array in my jObject and have it added to a list of type would be very helpful.
Class Definition
public class EventManagerLogEntry
{
public int a { get; set; }
public string b { get; set; }
public string c { get; set; }
public string d { get; set; }
public int e { get; set; }
public string f { get; set; }
public string g { get; set; }
public string h { get; set; }
public string i { get; set; }
public string j { get; set; }
public int k { get; set; }
public int l { get; set; }
public string m { get; set; }
public string n { get; set; }
public int o { get; set; }
public int p { get; set; }
public string q { get; set; }
public string r { get; set; }
public int s { get; set; }
}
UPDATE
I tried several different methods and this seems to be working for me.
[HttpPost]
public HttpResponseMessage Post([FromBody] JArray test)
{
var list = JsonConvert.DeserializeObject<List<EventManagerLogEntry>>(test.ToString());
foreach (EventManagerLogEntry x in list)
{
//_context.EventManagerLogEntry.Attach(x);
//_context.SaveChanges();
}
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
}

Use this model to deserialize your json
public class Log
{
public List<Dictionary<string,string>> LogEntry { get; set; }
}
var log = JsonConvert.DeserializeObject<Log>(json);
You can also use linq
var jObj = JObject.Parse(json);
var listOfDict = jObj["LogEntry"]
.Select(x => x.Cast<JProperty>()
.ToDictionary(p => p.Name, p => p.Value))
.ToList();

Just change your model to this.
public class EventManagerLogEntry
{
[JsonProperty("LogEntry")]
public List<Node> LogEntries { get; set; }
}
public class Node
{
public int a { get; set; }
public string b { get; set; }
public string c { get; set; }
public string d { get; set; }
public int e { get; set; }
public string f { get; set; }
public string g { get; set; }
public string h { get; set; }
public string i { get; set; }
public string j { get; set; }
public int k { get; set; }
public int l { get; set; }
public string m { get; set; }
public string n { get; set; }
public int o { get; set; }
public int p { get; set; }
public string q { get; set; }
public string r { get; set; }
public int s { get; set; }
}
And simple deserialize object.
var obj = JsonConvert.DeserializeObject<EventManagerLogEntry>(yourjson);

There are a couple improvements you can make to get this working. First thing is that you should not need to deserialize your json manually.
public class Value
{
public String Name { get; set; }
}
...
[HttpPost("one")]
public void Post([FromBody] Value value)
{
Console.WriteLine("got one");
}
[HttpPost("many")]
public void Post([FromBody] Value[] value)
{
Console.WriteLine("got many");
}
you can use the class definition in the POST methods to automatically get the objects from the json.
Second you can do one of two things:
Post only the array json to the server and use an array
Create a new model that encapsulates your list as #L.B has mentioned.
Below are the json data sent to the above routes that work.
One
{ "name" : "test" }
Many
[{ "name" : "test" }]

Related

Problem Deserializing JSON to objects in C#

I have the below response from the API in a console application written in C#:
{
"d": {
"results": [
{
"__metadata": {
"id": "123",
"uri": "456",
"type": "789"
},
"PERNR": "1",
"USRID": "2"
},
{
"__metadata": {
"id": "159",
"uri": "951",
"type": "753"
},
"PERNR": "4",
"USRID": "6"
}
]
}
}
And used the below code to deserialize:
public class d
{
public results results { get; set; }
}
public class results
{
public string PERNR { get; set; }
public string USRID { get; set; }
public __metadata __metadata { get; set; }
}
public class __metadata
{
public string id { get; set;}
public string uri { get; set; }
public string type { get; set; }
}
var serilizer = new JavaScriptSerializer();
d output = serilizer.Deserialize<d>(response.Content);
But the result is null. Is there any problem in the definition of the classes?
The properties should start with a capital letter, to match the case of the properties in the JSON response. Change the class definitions as follows:
public class D
{
public Results[] results { get; set; }
}
public class Results
{
public string PERNR { get; set; }
public string USRID { get; set; }
public Metadata __metadata { get; set; }
}
public class Metadata
{
public string id { get; set;}
public string uri { get; set; }
public string type { get; set; }
}
Change deserialize line to:
var serilizer = new JavaScriptSerializer();
D output = serilizer.Deserialize<D>(response.Content);
The issue is results is an array in your json, where in your class, it is an object. Change it to
public class d
{
public Result[] results { get; set; }
}
If you use a JSON to C# converter like json2csharp or Visual Studio's Paste JSON As Classes you'll get :
public class Root
{
public D d { get; set; }
}
public class D
{
public List<Result> results { get; set; }
}
public class Metadata
{
public string id { get; set; }
public string uri { get; set; }
public string type { get; set; }
}
public class Result
{
public Metadata __metadata { get; set; }
public string PERNR { get; set; }
public string USRID { get; set; }
}
There are two important differences :
The JSON document contains a root element with an attribute named d, not a D object
D.results is a collection of Result objects, not a single object

Unable to Parsing nested Json file in C#

I have Json format response from a API call and I want to map the data from the response to each varibales.
Json format
{
"success": true,
"data": {
"students": [
{
"Admission_date": "2018-05-01",
"Name": "Sree",
"Branch": "Electronics",
"Semester": "2",
"HOD": "Mahesh",
},
{
"Admission_date": "2018-05-01",
"Name": "Naresh",
"Branch": "Electronics",
"Semester": "2",
"HOD": "Mahesh",
}
],
"remaining": 0
}
}
I have tried to parse the JSON response and then to load the value through for each. But I'm not able to achieve the solution.
JObject jsonparsing1 = JObject.Parse(str4); //str4;- Json value
var token1 = (JArray)jsonparsing1.SelectToken("data");
var token2 = (JArray)jsonparsing1.SelectToken("data[0]Students");
JArray abc = JsonConvert.DeserializeObject<JArray>(token2.ToString());
foreach (var test in abc)
{
String Admission_date=test["Admission_date"];
String Name=test["Name"];
String Branch=test["Branch"];
String Semester=test["Semester"];
String HOD=test["HOD"];
String remaining=test["remaining"];
}
Expected result
String Admission_date=Admission_date
String Name=Name
String Branch=Branch
String Semester=Semester
String HOD=HOD
String remaining=remaining
Could anyone please help me on this?
I think you can use this sample:
public class JsonData
{
public bool success { get; set; }
public Data data { get; set; }
}
public class Data
{
public Data()
{
this.students = new List<Student>();
}
public List<Student> students { get; set; }
public int remaining { get; set; }
}
public class Student
{
public string Admission_date { get; set; }
public string Name { get; set; }
public string Branch { get; set; }
public string Semester { get; set; }
public string HOD { get; set; }
}
And then:
JsonData abc = JsonConvert.DeserializeObject<JsonData>(token2.ToString());
I will do this way!
public class Student
{
public string Admission_date { get; set; }
public string Name { get; set; }
public string Branch { get; set; }
public string Semester { get; set; }
public string HOD { get; set; }
}
public class Data
{
public List<Student> students { get; set; }
public int remaining { get; set; }
}
public class RootObject
{
public bool success { get; set; }
public Data data { get; set; }
}
and in C# Code Just use only below line:
var obj = JsonConvert.DeserializeObject<RootObject>("{ \"success\": true,\"data\": {\"students\": [{ \"Admission_date\": \"2018-05-01\",\"Name\": \"Sree\",\"Branch\":\"Electronics\",\"Semester\": \"2\",\"HOD\": \"Mahesh\",}],\"remaining\": 0}}");
use
foreach(var item in obj.data.students)
{
// Access Admission_date etc.
string name = item.Name;
}
dotnetfiddle

Cannot get value from nested json

I'm deserializing a JSON object into a class that I created using json2csharp. Once deserialized, I cannot access the nested values of this object. The error I get is this:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
This is the class I created;
public class Ticker
{
public List<object> error { get; set; }
public Result result { get; set; }
public class Result
{
public XXBTZCAD XBTCAD { get; set; }
public class XXBTZCAD
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
}
}
Here is the JSON string, at the time of this writing:
{
"error": [
],
"result": {
"XXBTZCAD": {
"a": [
"4776.10000",
"8",
"8.000"
],
"b": [
"4773.90000",
"1",
"1.000"
],
"c": [
"4776.20000",
"0.02510294"
],
"v": [
"4.85183508",
"61.15237421"
],
"p": [
"4775.02293",
"4767.92898"
],
"t": [
126,
608
],
"l": [
"4756.70000",
"4720.60000"
],
"h": [
"4780.00000",
"4783.30000"
],
"o": "4776.40000"
}
}
}
This is the code that deserializes and attempts to display the first value of List a
private async void GetKraken(object sender, RoutedEventArgs e)
{
var client = new RestClient();
IRestResponse response;
Ticker BTCCADTicker = new Ticker();
client.BaseUrl = new Uri("https://api.kraken.com/0/public/Ticker?pair=XBTCAD");
var request = new RestRequest();
response = await client.ExecuteTaskAsync(request);
BTCCADTicker = JsonConvert.DeserializeObject<Ticker>(response.Content);
MessageBox.Show(BTCCADTicker.result.XBTCAD.a[0]);
}
I would expect to see a value around 4700 to be returned, but I'm getting the error above instead. What gives? Any help is appreciated.
You haven't defined XXBTZCAD in your model. You've called it XBTCAD by mistake. Fixed it looks like this:
public class Ticker
{
public List<object> error { get; set; }
public Result result { get; set; }
public class Result
{
public XXBTZCAD XXBTZCAD { get; set; }
public class XXBTZCAD
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
}
}
I see now that this is the same name as the nested class. I'd recommend the simple solution of not nesting your classes:
public class Ticker
{
public List<object> error { get; set; }
public Result result { get; set; }
}
public class Result
{
public XXBTZCAD XXBTZCAD { get; set; }
}
public class XXBTZCAD
{
public List<string> a { get; set; }
public List<string> b { get; set; }
public List<string> c { get; set; }
public List<string> v { get; set; }
public List<string> p { get; set; }
public List<int> t { get; set; }
public List<string> l { get; set; }
public List<string> h { get; set; }
public string o { get; set; }
}
If you really want to nest them, simply rename class XXBTZCAD to something else. It's the property name that's important for deserialization, not the type name.
I suggest copy your JSON and in Visual Studio :
Edit > Paste Special > Parse JSON As Classes
public class Ticker
{
public object[] error { get; set; }
public Result result { get; set; }
}
public class Result
{
public XXBTZCAD XXBTZCAD { get; set; }
}
public class XXBTZCAD
{
public string[] a { get; set; }
public string[] b { get; set; }
public string[] c { get; set; }
public string[] v { get; set; }
public string[] p { get; set; }
public int[] t { get; set; }
public string[] l { get; set; }
public string[] h { get; set; }
public string o { get; set; }
}
and you can use this method to get the result :
public static async Task<string> GetKraken()
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://api.kraken.com/0/public/Ticker?pair=XBTCAD");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
and then use the method and convert it to get actual object:
var ticker = JsonConvert.DeserializeObject<Ticker>(GetKraken().Result);

Convert Json to List<object> with .NET

After days to try to convert Json to List of objects, I'm here.
I have a REST API that return the Json string:
{
GetItemsListResult:"[
{
"code":"VOL00056",
"clsID":223108653,
"type":2,
"status":1,
"free":0.0,
"total":671088640.0,
"perc":99,
"descr":"no mailing",
"dt":20160926,
"tm":112456,
"full":1
},
{
"code":"VOL00055",
"clsID":111760419,
"type":2,
"status":1,
"free":0.0,
"total":671088640.0,
"perc":99,
"descr":"Email",
"dt":20160817,
"tm":222411,
"full":1
}
]"
}
I know that this string comes from a DataTable:
String JSONresult = JsonConvert.SerializeObject(ds.Tables[0]);
I created two class: one that describe the object model and another that get the collection. But when trying to
VolumeCollection volumes = Newtonsoft.Json.JsonConvert.DeserializeObject<VolumeCollection>(listVolumes);
I obtain
Could not cast or convert from System.String to System.Collections.Generic.List`1[Volume].
What is wrong?
Volume Class:
public class Volume
{
public String code { get; set; }
public Int32 classId { get; set; }
public Byte volumeType { get; set; }
public Byte status { get; set; }
public float freeSpace { get; set; }
public float totalSpace { get; set; }
public Int16 fillPercentage { get; set; }
public String classDescription { get; set; }
public Int32 closeDate { get; set; }
public Int32 closeTime { get; set; }
public Boolean isFull { get; set; }
}
The json string received is:
"\"
[{\\"FreeSpace\\":0.0,\\"TotalSpace\\":671088640.0,\\"FillPercentage\\":99,\\"ClassDescription\\":\\"Email esterne\\",\\"CloseDate\\":20161001,\\"CloseTime\\":212512,\\"IsFull\\":true,\\"VolumeType\\":2,\\"ClassId\\":111760419,\\"Code\\":\\"VOL00057\\",\\"Status\\":1},
{\\"FreeSpace\\":0.0,\\"TotalSpace\\":671088640.0,\\"FillPercentage\\":99,\\"ClassDescription\\":\\"Corrispondenza no mailing\\",\\"CloseDate\\":20160926,\\"CloseTime\\":112456,\\"IsFull\\":true,\\"VolumeType\\":2,\\"ClassId\\":223108653,\\"Code\\":\\"VOL00056\\",\\"Status\\":1}
]\""
It seems to be a not valid json...
Given that your json is not valid and given that the following is:
{
"GetItemsListResult": [{
"code": "VOL00056",
"clsID": 223108653,
"type": 2,
"status": 1,
"free": 0.0,
"total": 671088640.0,
"perc": 99,
"descr": "no mailing",
"dt": 20160926,
"tm": 112456,
"full": 1
}, {
"code": "VOL00055",
"clsID": 111760419,
"type": 2,
"status": 1,
"free": 0.0,
"total": 671088640.0,
"perc": 99,
"descr": "Email",
"dt": 20160817,
"tm": 222411,
"full": 1
}]
}
using the following classes that I generated, this works:
public class GetItemsListResult
{
public string code { get; set; }
public int clsID { get; set; }
public int type { get; set; }
public int status { get; set; }
public double free { get; set; }
public double total { get; set; }
public int perc { get; set; }
public string descr { get; set; }
public int dt { get; set; }
public int tm { get; set; }
public int full { get; set; }
}
public class RootObject
{
public List<GetItemsListResult> GetItemsListResult { get; set; }
}
var res = JsonConvert.DeserializeObject<RootObject>(json);
N.B: this site generated the classes from the JSON: json2csharp
Your GetItemsListResult is a string, not an array. Notice the double quotes:
GetItemsListResult: "[
So, ideally you want to fix your json to be a real array.
If you don't have control over the json, then as a poor alternative you could recursively parse the strings to extract the array.
you have invalid json string:
1.1 valid json like this:
{
"GetItemsListResult":[
{"code":"VOL00056","clsID":223108653,"type":2,"status":1,"free":0.0,"total":671088640.0,"perc":99,"descr":"no mailing","dt":20160926,"tm":112456,"full":1},
{"code":"VOL00055","clsID":111760419,"type":2,"status":1,"free":0.0,"total":671088640.0,"perc":99,"descr":"Email","dt":20160817,"tm":222411,"full":1}
]
}
With http://json2csharp.com/ build data model
2.1 like this:
public class GetItemsListResult
{
public string code { get; set; }
public int clsID { get; set; }
public int type { get; set; }
public int status { get; set; }
public double free { get; set; }
public double total { get; set; }
public int perc { get; set; }
public string descr { get; set; }
public int dt { get; set; }
public int tm { get; set; }
public int full { get; set; }
}
public class RootObject
{
public List<GetItemsListResult> GetItemsListResult { get; set; }
}
with http://www.newtonsoft.com/json help parse you json
3.1 like this:
var jsonObj = JsonConvert.DeserializeObject<RootObject>(jsonString);

How can I deserialize JSON into this POCO class?

ERROR:
Cannot implicitly convert type 'UserItem' to 'RootObject'
How can I deserialize JSON into this POCO class?
I'm simply trying to deserilize json data into C# custom poco class as shown below and here is what i have done so far;
public static UserItem DownloadJSONString(string urlJson)
{
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString(urlJson);
UserItem userItems = JsonConvert.DeserializeObject<RootObject>(json);
return userItems;
}
}
I'm kind of stuck here
here my Json:
{
"meta":
{
"status":200,
"resultSet":
{
"id":"05"
},
"pagination":
{
"count":2,
"pageNum":1,
"pageSize":2
}
},
"results":
{
"id":0,
"name":
"title",
"items":
[
{
"id":0,
"name":"English",
"title":"English",
},
{
"id":0,
"name":"Spanish",
"title":"Spanish;",
}
]
}
}
here is my json object (generate from json to c# class)
public class ResultSet
{
public string id { get; set; }
}
public class Pagination
{
public int count { get; set; }
public int pageNum { get; set; }
public int pageSize { get; set; }
}
public class Meta
{
public int status { get; set; }
public ResultSet resultSet { get; set; }
public Pagination pagination { get; set; }
}
public class Item
{
public int id { get; set; }
public string name { get; set; }
public string title { get; set; }
}
public class Results
{
public int id { get; set; }
public string name { get; set; }
public List<Item> items { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
public Results results { get; set; }
}
Here is my simple UserItem POCO class
public class UserItem
{
public int id { get; set; }
public string name { get; set; }
public string title { get; set; }
}
Here you go:
var root = JsonConvert.DeserializeObject<RootObject>(json);
var userItem = root.results.items
.Select(i => new UserItem
{
id = i.id,
name = i.name,
title = i.title
}).FirstOrDefault();
return userItem;
As you already know, you can't just convert the Item class into a UserItem, but you can build one. One thing to note here is that obviously if you only want to return one you'll have to just grab one. Here I've grabbed the first or default. The default would be null if the list were empty for example.

Categories

Resources