Not able to convert string to json - c#

i am getting measurements from withings and want to show them in graphs but not able to convert it to json. i also try JsonConvert.SerializeObject(myString) using Newtonsoft.dlland simple
System.Web.Script.Serialization.JavaScriptSerializer sr = new System.Web.Script.Serialization.JavaScriptSerializer();
sr.Serialize(myString);
but it is not converting.
My withings measurement string is as follows.
{
"status": 0,
"body": {
"updatetime": 1392764547,
"measuregrps": [
{
"grpid": 17945868,
"attrib": 0,
"date": 139984270,
"category": 1,
"measures": [
{
"value": 72,
"type": 9,
"unit": 0
},
{
"value": 152,
"type": 10,
"unit": 7
},
{
"value": 87,
"type": 17,
"unit": 0
}
]
},
{
"grpid": 176587495,
"attrib": 0,
"date": 13915689,
"category": 1,
"measures": [
{
"value": 94,
"type": 9,
"unit": 0
},
{
"value": 145,
"type": 10,
"unit": 0
},
{
"value": 109,
"type": 11,
"unit": 0
}
]
},
{
"grpid": 179262494,
"attrib": 0,
"date": 1391369607,
"category": 1,
"measures": [
{
"value": 77,
"type": 9,
"unit": 0
},
{
"value": 121,
"type": 10,
"unit": 0
},
{
"value": 87,
"type": 11,
"unit": 0
}
]
},
{
"grpid": 179258492,
"attrib": 0,
"date": 1391171167,
"category": 1,
"measures": [
{
"value": 61,
"type": 9,
"unit": 0
},
{
"value": 107,
"type": 10,
"unit": 0
},
{
"value": 80,
"type": 11,
"unit": 0
}
]
},
{
"grpid": 179089150,
"attrib": 0,
"date": 1391167537,
"category": 1,
"measures": [
{
"value": 69,
"type": 9,
"unit": 0
},
{
"value": 112,
"type": 10,
"unit": 0
},
{
"value": 67,
"type": 11,
"unit": 0
}
]
},
{
"grpid": 179079661,
"attrib": 2,
"date": 1391164672,
"category": 1,
"measures": [
{
"value": 720,
"type": 1,
"unit": -1
}
]
},
{
"grpid": 17998560,
"attrib": 2,
"date": 146989672,
"category": 1,
"measures": [
{
"value": 284,
"type": 4,
"unit": -2
}
]
}
]
}
}

It seems, you want to deserialize your json string, not serialize:
var obj = JsonConvert.DeserializeObject<Withings.RootObject>(json);
public class Withings
{
public class Measure
{
public int value { get; set; }
public int type { get; set; }
public int unit { get; set; }
}
public class Measuregrp
{
public int grpid { get; set; }
public int attrib { get; set; }
public int date { get; set; }
public int category { get; set; }
public List<Measure> measures { get; set; }
}
public class Body
{
public int updatetime { get; set; }
public List<Measuregrp> measuregrps { get; set; }
}
public class RootObject
{
public int status { get; set; }
public Body body { get; set; }
}
}

JsonConvert.SerializeObject(myString) takes an object an returns a string. If you want to turn a string into an object you want to use Deserialize<T>(sting json). Given the arguments name in your sample is myString I would assume you're using the method wrong.
To deserialize you need an equivalent type like;
public class myObject
{
public int status { get; set; }
public Body body { get; set; }
}
public class Body
{
//other parameters ect
}
Your object model needs to exactly match the json in order by Deserialize<T> to behave correctly.

Related

Shorten JSON reading class

I have a simple JSON reading class that should grab values from a JSON object and put it in c# variables. Right now it uses 8 if statements, but I was wondering if this can be done in a smoother way.
current code:
public Game Read(string filePath)
{
string fileName = "./Levels/TempleOfDoom.json";
JObject json = JObject.Parse(File.ReadAllText(fileName));
Game game = new Game();
foreach (JObject jconnection in json["rooms"])
{
Room room = new Room();
foreach (JProperty jProperty in jconnection.Children().OfType<JProperty>())
{
if (jProperty.Name == "id")
room.id = jProperty.Value.ToObject<int>();
if (jProperty.Name == "width")
room.width = jProperty.Value.ToObject<int>();
if (jProperty.Name == "height")
room.height = jProperty.Value.ToObject<int>();
foreach (JObject jconnection2 in jconnection["items"])
{
Item item = new Item();
foreach (JProperty jProperty2 in jconnection.Children().OfType<JProperty>())
{
if (jProperty.Name == "type")
item.type = jProperty2.Value.ToObject<string>();
if (jProperty.Name == "x")
item.x = jProperty2.Value.ToObject<int>();
if (jProperty.Name == "y")
item.y = jProperty2.Value.ToObject<int>();
if (jProperty.Name == "damage")
item.damage = jProperty2.Value.ToObject<int>();
if (jProperty.Name == "color")
item.color = jProperty2.Value.ToObject<string>();
}
}
}
game.Rooms.Add(room);
}
return game;
}
relevant part of JSON object:
{
"rooms": [
{
"id": 1,
"type": "room",
"width": 5,
"height": 5
},
{
"id": 2,
"type": "room",
"width": 3,
"height": 3
},
{
"id": 3,
"type": "room",
"width": 5,
"height": 5,
"items": [
{
"type": "disappearing boobietrap",
"damage": 1,
"x": 2,
"y": 1
},
{
"type": "sankara stone",
"x": 2,
"y": 2
}
]
},
{
"id": 4,
"type": "room",
"width": 11,
"height": 7,
"items": [
{
"type": "key",
"color": "green",
"x": 1,
"y": 1
},
{
"type": "sankara stone",
"x": 5,
"y": 3
},
{
"type": "boobietrap",
"damage": 1,
"x": 4,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 5,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 6,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 4,
"y": 4
},
{
"type": "boobietrap",
"damage": 1,
"x": 5,
"y": 4
},
{
"type": "boobietrap",
"damage": 1,
"x": 6,
"y": 4
}
]
},
{
"id": 5,
"type": "room",
"width": 5,
"height": 5,
"items": [
{
"type": "key",
"color": "red",
"x": 2,
"y": 3
},
{
"type": "sankara stone",
"x": 2,
"y": 2
}
]
},
{
"id": 6,
"type": "room",
"width": 3,
"height": 3,
"items": [
{
"type": "sankara stone",
"x": 1,
"y": 1
}
]
},
{
"id": 7,
"type": "room",
"width": 5,
"height": 3,
"items": [
{
"type": "pressure plate",
"x": 2,
"y": 1
}
]
},
{
"id": 8,
"type": "room",
"width": 3,
"height": 3
},
{
"id": 9,
"type": "room",
"width": 5,
"height": 5,
"items": [
{
"type": "sankara stone",
"x": 2,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 1,
"y": 3
},
{
"type": "boobietrap",
"damage": 1,
"x": 2,
"y": 3
},
{
"type": "boobietrap",
"damage": 1,
"x": 3,
"y": 3
}
]
}
],
}
As you can see, each room has an ID, width and height (type can be ignored) and some rooms have items, which all have a type, x and y coordinate, and some have colors or damage numbers. Is there a better way to get all of these values into a C# class? A game has a List of rooms, and each room can possibly have a list of items.
EDIT: Thanks guys! These lines of code did exactly what I wanted (together with some extra classes for each object game/player/item etc.
public Game Read(string fileName)
{
JObject json = JObject.Parse(File.ReadAllText(fileName));
return JsonConvert.DeserializeObject<Game>(json.ToString());
}
My advice would be to use a webpage called https://json2csharp.com/ that it will create the model class for your json. Sometimes it needs a little tweaking, then is as easy as calling
var json = JsonConverter.DeserializeObject<YourJsonClass>(File.ReadAllText(fileName))
And you would have a class representing your json file, and if you still need to move this information to your custom classes you wouldnt need the if at all just do something like
foreach (var jsonRoom in json.Rooms)
{
room.id = jsonRoom.id;
//and so on
}
You can create a class, for example:
public class Item
{
public string type { get; set; }
public int damage { get; set; }
public int x { get; set; }
public int y { get; set; }
public string color { get; set; }
}
public class Room
{
public int id { get; set; }
public string type { get; set; }
public int width { get; set; }
public int height { get; set; }
public List<Item> items { get; set; }
}
public class MyClass
{
public List<Room> rooms { get; set; }
}
And then deserialize the object as:
MyClass myDeserializedClass = JsonConvert.DeserializeObject<MyClass>(json.ToString());
And then you can access all inside of MyClass and iterate over List<Room> using foreach

Can not deserialize json to Dictionary<string, List<Purchase>>

I can not deserialize json to Dictionary<string, List<Purchas>> in C#.
Here is my .json:
{
"Ukraine": {
{
"Credits": 500,
"Name": "Clever goat",
"Price": {
"Amount": 100,
"Currency": "UAH"
}
},
{
"Credits": 1000,
"Name": "Smart hare",
"Price": {
"Amount": 190,
"Currency": "UAH"
}
}
},
"USA": {
{
"Credits": 500,
"Name": "Clever goat",
"Price": {
"Amount": 10,
"Currency": "USD"
}
},
{
"Credits": 1000,
"Name": "Smart hare",
"Price": {
"Amount": 19,
"Currency": "USD"
}
}
}
}
Here is my Purchase class:
public class Price
{
public int Amount { get; set; }
public string Currency { get; set; }
}
public class Purchase
{
public int Credits { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}
Here is how I am trying to deserialize it:
var countryToPurchases = JsonConvert.DeserializeObject<Dictionary<string, List<Purchase>>>(dataJSON);
Here is the error I am getting:
JsonReaderException: Invalid property identifier character: {. Path 'Ukraine', line 3, position 4.
Newtonsoft.Json.JsonTextReader.ParseProperty()
What am I missing here?
You have two problems here:
The Json is invalid. There should be arrays there but there aren't.
A valid json would look like this:
[
{
"Ukraine": [
{
"Credits": 500,
"Name": "Clever goat",
"Price": {
"Amount": 100,
"Currency": "UAH"
}
},
{
"Credits": 1000,
"Name": "Smart hare",
"Price": {
"Amount": 190,
"Currency": "UAH"
}
}
]
},
{
"USA": [
{
"Credits": 500,
"Name": "Clever goat",
"Price": {
"Amount": 10,
"Currency": "USD"
}
},
{
"Credits": 1000,
"Name": "Smart hare",
"Price": {
"Amount": 19,
"Currency": "USD"
}
}
]
}
]
The Price property should be of type Price, not int.
public class Purchase
{
public int Credits { get; set; }
public string Name { get; set; }
public Price Price { get; set; }
}
please check this json and see if it's works :
{
"Ukraine": {
"Credits": 500,
"Name": "Clever goat",
"Price": {
"Amount": 100,
"Currency": "UAH"
}
},
"USA": {
"Credits": 500,
"Name": "Clever goat",
"Price": {
"Amount": 10,
"Currency": "USD"
}
}
}

Sort the sum aggregate - Nest (ElasticSearch)

The requirement is to group by Employee Id and Name and then aggregate the sum(salary). I have managed to get it to work. However, the final aggregated result has to be sorted in descending order of the sum. I tried couple of ways but the ordering doesn't seem to work.
var resp =
elasticClient.Search<Employee>(
k => k.Size(0).Query(q => q.QueryString(s => s.Query(query)))
.Aggregations(a => a.Terms("EmpId", v => v.Field(f => f.EmpId)
.Aggregations(aa => aa.Terms("EmpName",vv => vv.Field(ff => ff.EmpName).OrderDescending("Salary")
.Aggregations(aaa => aaa.Sum("Salary", sa => sa.Field(fff => fff.Salary))))))));
Employee Class:
public sealed class Employee
{
public long Id { get; set; }
public int DateId { get; set; }
public int? DivisionNumber { get; set; }
public string Manager { get; set; }
public decimal Salary { get; set; }
public int UpdateId { get; set; }
public DateTime UpdateTimestamp { get; set; }
public int EmpId { get; set; }
public string EmpName { get; set; }
}
Mapping:
POST /sample_employee
{
"mappings": {
"post":{
"properties": {
"empId": {
"type" : "long"
},
"empName": {
"type": "string",
"index": "not_analyzed"
},
"salary": {
"type": "float"
},
"dateId": {
"type": "long"
},
"divisionNumber":{
"type": "long"
}
}
}
}
}
Query for aggregation:
GET /sample_employee/_search
{
"size": 0,
"query": {
"query_string": {
"query": "dateId:(1780) AND divisionNumber:(1)"
}
},
"aggs": {
"EmpId": {
"terms": {
"field": "empId"
},
"aggs": {
"EmpName": {
"terms": {
"field": "empName",
"size": 30,
"order":{
"Amount.value": "desc"}
},
"aggs": {
"Amount": {
"sum": {
"field": "salary"
}
}
}
}
}
}
}
}
Response:
"aggregations": {
"EmpId": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 10,
"doc_count": 1,
"EmpName": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Jerry Mathews",
"doc_count": 1,
"Amount": {
"value": 10000
}
}
]
}
},
{
"key": 11,
"doc_count": 1,
"EmpName": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Tom Raju",
"doc_count": 1,
"Amount": {
"value": 15000
}
}
]
}
},
{
"key": 12,
"doc_count": 1,
"EmpName": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Nel Gad",
"doc_count": 1,
"Amount": {
"value": 20000
}
}
]
}
},
{
"key": 13,
"doc_count": 1,
"EmpName": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Jim Thomas",
"doc_count": 1,
"Amount": {
"value": 25000
}
}
]
}
},
{
"key": 14,
"doc_count": 1,
"EmpName": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Amat Ahu",
"doc_count": 1,
"Amount": {
"value": 30000
}
}
]
}
}
]
}
}
}

Difficulty deserialising nested JSON

I am calling a REST service to get back a JSON structure.
The error I get is
Test method BarPanda.Web.Services.Test.PosServiceTests.GetMenu threw exception:
System.MissingMethodException: No parameterless constructor defined for this object.
The original JSON is as follows (partial)
{
"count": 3,
"limit": 50,
"_links": {
"self": {
"etag": "b49a27c7e7c663af8d6a736e24fac7f5",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/categories/" ,
"profile": "https://panel.omnivore.io/docs/api#category_list" 
}
},
"_embedded": {
"categories": [
{
"id": "AdiRjiAp",
"name": "Drinks",
"_links": {
"items": {
"etag": "05dad4d734401321a4854cf4f0369102",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/categories/AdiRjiAp/items/" ,
"profile": "https://panel.omnivore.io/docs/api#menu-item_list" 
},
"self": {
"etag": "05dad4d734401321a4854cf4f0369102",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/categories/AdiRjiAp/" ,
"profile": "https://panel.omnivore.io/docs/api#category_retrieve" 
}
},
"_embedded": {
"items": [
{
"id": "gki84ia9",
"in_stock": true,
"modifier_groups_count": 0,
"name": "Soda",
"open": false,
"pos_id": "gki84ia9",
"price": 150,
"price_levels": [
{
"id": "Byineidy",
"price": 150
},
{
"id": "g4T4dTBj",
"price": 200
},
{
"id": "K6czkc8b",
"price": 250
}
],
"_links": {
"modifier_groups": {
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/gki84ia9/modifier_groups/" ,
"profile": "https://panel.omnivore.io/docs/api#modifier-group_list" 
},
"self": {
"etag": "c59b380aed5c1f33915b028b739df955",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/gki84ia9/" ,
"profile": "https://panel.omnivore.io/docs/api#menu-item_retrieve" 
}
}
},
{
"id": "doTaLTyg",
"in_stock": true,
"modifier_groups_count": 0,
"name": "Orange Juice",
"open": false,
"pos_id": "doTaLTyg",
"price": 175,
"price_levels": [
{
"id": "L4iqKid8",
"price": 175
},
{
"id": "K6T8MTzb",
"price": 300
}
],
"_links": {
"modifier_groups": {
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/doTaLTyg/modifier_groups/" ,
"profile": "https://panel.omnivore.io/docs/api#modifier-group_list" 
},
"self": {
"etag": "d3ae9754edb321f18e192ebea446baeb",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/doTaLTyg/" ,
"profile": "https://panel.omnivore.io/docs/api#menu-item_retrieve" 
}
}
}
]
}
},
I am trying to deserialize it with the following code and object classes
var response = _client.Execute(request);
var converter = new JsonDeserializer();
var menu = converter.Deserialize<PosMenu>(response);
PosMenu
[DataContract]
public class PosMenu
{
[DataMember]
public int VenueId { get; set; }
[DataMember]
public int count { get; set; }
[DataMember]
public PosMenuEmbedded _embedded { get; set; }
}
PosMenuEmbedded
[DataContract]
public class PosMenuEmbedded
{
[DataMember]
public long UniqueId { get; set; }
[DataMember]
public PosMenuCategory[] categories { get; set; }
[DataMember]
public int PosMenuId { get; set; }
}
PosMenuCategory
[DataContract]
public class PosMenuCategory
{
}
Note: I have taken all properties out of this class for now just to see if I could get it working with a blank class, but alas not.
If I comment out the line in PosMenuEmbedded
public PosMenuCategory[] categories { get; set; }
It succeeds. If I put it back in, it fails, even with an empty class.
Can anyone suggest why this might be?
[DataMember]
public List<PosMenuCategory> categories { get; set; }

Web Api; Entity Framework; Data returns recursive

im facing a problem with probably selfreference Looping:
Model:
public class ProtectedAccount
{
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Created { get; private set; }
public DateTime? Changed { get; set; }
public bool Disabled { get; set; }
public virtual ICollection<ProtectedAccountMember> Members { get; set; }
public virtual ProtectedAccountType Type { get; set; }
}
public class ProtectedAccountMember
{
public int Id { get; set; }
[StringLength(300)]
public string Name { get; set; }
[Index]
public virtual ProtectedAccount ProtectedAccount { get; set; }
}
Controller:
[ResponseType(typeof(ProtectedAccount))]
[Route("ProtectedAccounts/{id}/Members")]
[HttpGet]
public IHttpActionResult GetProtectedAccountMembers(int id)
{
var protectedAccount = db.ProtectedAccounts.Find(id);
if (protectedAccount == null)
{
return NotFound();
}
return Ok(protectedAccount.Members.ToList());
}
the data wich i receive for an GET seems to Loop recursive through all navigations:
[
{
"ProtectedAccount": {
"Members": [
{
"Id": 2,
"Name": "XXX, XX",
},
{
"Id": 3,
"Name": "XX, XX",
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 1,
"Name": "test",
},
{
"ProtectedAccount": {
"Members": [
{
"Id": 1,
"Name": "test",
},
{
"Id": 3,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXXX",
},
"Id": 2,
"Name": "XX, XX",
},
{
"ProtectedAccount": {a
"Members": [
{
"Id": 1,
"Name": "test",
"SamAccountName": "XXX",
"Disabled": false
},
{
"Id": 2,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 3,
"Name": "XX, XX",
}
]
There is only one "ProtectedAccount" in the database. DO i have to use DTO to overcome this issue? I tried some configuration via the json formatsettings but didnt get any better results.
From your code, you are only returing the protectedAccount.Members, hence you could do a projection query as below
var results = ctx.ProtectedAccountMembers
.Where(member => member.ProtectedAccount.Id == protectedAccount.Id)
.Select(member => new { member.Id, member.Name }).ToList();

Categories