Deserialize JSON (Json.NET) - c#

I need a little help with json deserialization. It's the first time I'm using Json, so I have just a little knowledge about it.
I get the following string using a webclient:
[{"name": "somename", "data": [[72, 1504601220], [null, 1504601280], ..., [125, 1504605840]]}]
and tried to serialize it with
JsonConvert.DeserializeObject<TestObject>(jsonstring)
My class looks like this:
public class TestObject
{
[JsonProperty(PropertyName = "name")]
public string TargetName { get; set; }
[JsonProperty(PropertyName = "data"]
public List<?????> DataPoints {get; set;}
}
How do I need to design my class to get the data values in some kind of collection so each entry contains the two values inside a bracket?
Thx for your patience and help!

Your data is a list of arrays containing nullable integers (by the looks of it)
[JsonProperty(PropertyName = "data"]
public List<int?[]> DataPoints {get; set;}

Try this website: http://json2csharp.com/
This website can save a lot of your time if you have just a plain JSON text. It helps you convert it to C# object, although you still have to double check it.
var data = "[{\"name\": \"somename\", \"data\": [[72, 1504601220], [null, 1504601280], [125, 1504605840]]}]";
var obj = JsonConvert.DeserializeObject<List<TestObject>>(data);
public class TestObject
{
[JsonProperty(PropertyName = "name")]
public string TargetName { get; set; }
[JsonProperty(PropertyName = "data")]
public List<int?[]> DataPoints { get; set; }
}

There is a some solution for this, C# 7.0 also supports ValueTuple such as this example.
List<(int? ,int?)> DataPoints { get; set; }
// if it not work try this.
List<List<int?>> DataPoints { get; set; }
If your json inner array elements count is equal to 2, so can assume to you use the value tuples.
Assume it is helpful for you.

Related

How to deserialize JSON with spaces in the attribute names?

I have a string array that I want to deserialize. Essentially, it is just a list of objects. Note that the attributes have spaces in the names:
[ { \"Event Name\": \"Hurricane Irma PR\", \"Storm Start (LST)\": \"2017-08-30\", \"Storm End (LST)\": \"2017-09-13\", \"Grid Cell Number\": 16412, \"Grid Cell State\": \"PR\", \"Grid Cell Name\": \"Grid26_0\", ...
I created a public class to template the string based on specific attributes that I want ( I don't want all the data) but I am not sure how to handle for the spaces in the names of the attributes that I want.
public class New_Events_Dataset
{
public string EventName { get; set; }
public string StormStart { get; set; }
public string StormEnd { get; set; }
public string GridCellState { get; set; }
public string GridCellName { get; set; }
public string USGSGageSiteNo { get; set; }
public string ReturnPeriodatGridCell { get; set; }
}
When I apply the deserializer with my class New_Events_Dataset like this:
var jsonResponse = returnJson.Deserialize<List<New_Events_Dataset>>(strresult);
string json = new JavaScriptSerializer().Serialize(jsonResponse);
return json;
I end up returning something like this. What am I doing wrong?
[{"EventName":null,"StormStart":null,"StormEnd":null,"GridCellState":null,"GridCellName":null,"USGSGageSiteNo":null,"ReturnPeriodatGridCell":null}
Unfortunately keys must match exactly each other.
One of the best ways to solve your problem is to define JsonProperty attribute for each property to get Deserialized object correctly. You can specify property's json key name with it.
You can take a look to this question and it's answer for better understanding:
An example of JsonProperty
Edit:
As in comments mentioned, because you are using JavaScriptSerializer JsonPropertyAttribute doesn't work in this situation.
But you can use it by adding Newtonsoft.Json Nuget Package and using it's deserilizer this way:
JsonConvert.DeserializeObject<AzureResourceData>(jsonString);

Modify a JSON string

I have a string in JSON format as follows
string jsonStr = "{"Type":1, "Id":1000,"Date":null,"Group": "Admin","Country":"India","Type":1}";
I want to modify this string so that Id attribute should always be the first. The order of attributes matters.
Is there any way I can modify this string.
I tried searching google but did not find appropriate solution.
Any help would be appreciated.
EDIT:
I also tried to deserialize object using
object yourOjbect = new JavaScriptSerializer().DeserializeObject(jsonStr);
But here also the "type" attribute comes first. I dont find any way to move the attributes within this deserialized object
It's possible. Use the JsonProperty attribute, property Order.
http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm.
Let me know if it works.
Instead of attempting to manipulate the order of the outputted JSON and comparing strings, I would transform both JSON strings that you want to compare, into objects and then perform your comparison. You could then compare individual properties or entire objects with something like the following:
void CompareJSON()
{
string json = #"{""Type"":1, ""Id"":1000,""Date"":null,""Group"": ""Admin"",""Country"":""India"",""Type"":1}";
string jsonToCompare = "JSON TO COMPARE";
MyObject myJsonObject = JsonConvert.DeserializeObject<MyObject>(json);
MyObject myJsonObjectToCompare = JsonConvert.DeserializeObject<MyObject>(jsonToCompare);
if (myJsonObject.Id == myJsonObjectToCompare.Id)
{
// Do something
}
}
class MyObject
{
public int Id { get; set; }
public int Type { get; set; }
public DateTime? Date { get; set; }
public string Group { get; set; }
public string Country { get; set; }
}
Please note that this example is carried out using the Newtonsoft.JSON library. More information on the library can be found here.
Just make your JSON into a c# class with Id first and then serialize it again if that is what you need. You do know that you have "Type" twice in the JSON string? In this solution it will get "fixed" so you only have it once as it should be. But if your string really is with two Type this wont work since the strings will be incorrect. If they really are like that you need to do some ugly string manipulation to fix the order but i hope the first string is incorrect only here and not in your code.
private void Test() {
string json = #"{""Type"":1, ""Id"":1000,""Date"":null,""Group"": ""Admin"",""Country"":""India"",""Type"":1}";
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
MyJsonObject myJsonObject = jsonSerializer.Deserialize<MyJsonObject>(json);
string s = jsonSerializer.Serialize(myJsonObject);
//Returns: {"Id":1000,"Type":1,"Date":null,"Group":"Admin","Country":"India"}
}
class MyJsonObject {
public int Id { get; set; }
public int Type { get; set; }
public DateTime? Date { get; set; }
public string Group { get; set; }
public string Country { get; set; }
}

How can I get values from a complex Json object?

I am trying to get values from Json objects that all are formed like this one:
http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=4798
I tried several libraries but none of them resulted in the way I wanted. I want to put the values into specific Datamembers.
This was my last attempt, it runs but it seems like my Datamembers are not getting any values.
namespace JSON_Data
{
public partial class Form1 : Form
public Form1()
{
InitializeComponent();
string jsonString = #"{""item"":{""icon"":""http://services.runescape.com/m=itemdb_rs/4996_obj_sprite.gif?id=4798"",""icon_large"":""http://services.runescape.com/m=itemdb_rs/4996_obj_big.gif?id=4798"",""id"":4798,""type"":""Ammo"",""typeIcon"":""http://www.runescape.com/img/categories/Ammo"",""name"":""Adamant brutal"",""description"":""Blunt adamantite arrow...ouch"",""current"":{""trend"":""neutral"",""price"":305},""today"":{""trend"":""neutral"",""price"":0},""members"":""true"",""day30"":{""trend"":""positive"",""change"":""+2.0%""},""day90"":{""trend"":""positive"",""change"":""+8.0%""},""day180"":{""trend"":""positive"",""change"":""+23.0%""}}}";
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Item));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
Item obj = (Item)ser.ReadObject(stream);
}
}
}
This is how my class "Item" looks
namespace JSON_Data
{
[DataContract]
public class Item
{
[DataMember]
public string Icon { get; set; }
[DataMember]
public string Icon_large { get; set; }
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public string Members { get; set; }
}
}
if you can try the Newtonsoft i can provide a way.. its very good and better approach as far as i think
var ob = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);
Item a = ((JObject)ob["item"]).ToObject<Item>();
There are several JSON serializers you can use in C#. Some have better performance, some have better fault tolerance and others have circular reference treatments.
In your case, I see that you simply want an object without passing it (to a WCF) anywhere. You can follow the second answer of this question: Deserialize JSON into C# dynamic object? Example code copied from that answer:
dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = stuff.Name;
string address = stuff.Address.City;
A dynamic object in C# allows you to read a property without declaring a class for it.

C# Json Deserialization

I have been asked to work with json data in order to create a quiz game in windows phone. I knew that I had to use json.net to achive this which I have previously used in the past but the method I used in the past is no useful here.
My question is this. I have this json string
[{"corr":"1","q":"text.","type":"0"},
{"corr":"0","q":"text.","type":"0"},
{"corr":"1","q":"text.","type":"0"},
{"corr":"0","q":"text.","type":"0"},
{"corr":"0","q":"text.","type":"0"},
{"corr":"1","q":"text.","type":"0"},
{"corr":"4","q":"text","a":["text","text","text","text"],"type":"1"},
{"corr":"2","q":"text","a":["text","text","text","text"],"type":"1"},
{"corr":"1","q":"text","a":["text","text","text","text"],"type":"1"},
{"corr":"2","q":"text","a":["22,2%","45%","54%","67%"],"type":"1"}]
and as you can image I want to fill some List with the properties above.
I have created the following class in order to represent the json objects
public class QuizObj
{
public string corr { get; set; }
public string q { get; set; }
public string type { get; set; }
public List<string> a { get; set; }
}
but I don't really know how to use it and can't find something really relevant.
Something like this should do the trick:
var quizObjs = JsonConvert.DeserializeObject<List<QuizObj>>(serializedStringValue);
string corr = quizObjs.First().corr;
// or
foreach(var quizObj in quizObjs)
{
string corr = quizObj.corr;
// etc
}
You will need to add a reference to NewtonSoft.Json, which you can get via NuGet (if you haven't already).

How to map JSON to C# Objects

I am having issues with understanding how to make this happen.
Basically we have an API, the user sends a JSON of the format:
{
"Profile":[
{
"Name":"Joe",
"Last":"Doe",
"Client":{
"ClientId":"1",
"Product":"Apple",
"Message":"Peter likes apples"
},
"Date":"2012-02-14"
}
]
}
I have a class called Profile with parameters Name, Last, and an object as one of its members called Client as well as property Date.
Something like this:
public class Profile {
public string Name {get; set;}
public string Last {get; set;}
public Client client {get; set;}
public DateTime dDate {get; set;}
}
So basically, I am not sure how to grab the JSON and then map it to my object.
Any help with "helping" me understand would be much appreciated.
You can use Json.NET to deserialize your json string as (with some modifications to your classes)
var yourObject = JsonConvert.DeserializeObject<Root>(jsonstring);
public class Root
{
public Profile[] Profile;
}
public class Profile
{
public string Name { get; set; }
public string Last { get; set; }
public Client Client { get; set; }
public DateTime Date { get; set; }
}
public class Client
{
public int ClientId;
public string Product;
public string Message;
}
You can use a JSON library for this, for example Newtonsoft.Json which is free. It will map json to your types automatically.
Sample:
public static T Deserialize<T>(string json)
{
Newtonsoft.Json.JsonSerializer s = new JsonSerializer();
return s.Deserialize<T>(new JsonTextReader(new StringReader(json)));
}
There is also a NuGet package available.
Easiest way I know is to use JSON.Net by newtonsoft.
To make it easier to understand, I always make matching classes in C# with the same name.
Then its easier to deserialize it.
As an example, if it is an array of objects in js, it will map to a list of object with the same names in C#.
As for the date time, its a bit tricky.
Id do the client side validation and Datetime.tryParse in the serverside, itll take care of the dashes or slashes.
var serializer = new JavaScriptSerializer();
List<abc> abcList = serializer.Deserialize<List<abc>>(PassedInJsonString);
I know this is a long time question, but I would like to add one more option, which does not use third party libraries, and only uses stock .Net libraries, and is available from .Net Core 3.1 onwards.
First of all, I leave a link to the official Microsoft documentation (where you will find examples on how to serialize and deserialize json strings): https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to
Let's build on your example. We have our starting json string:
{
"Profile":[
{
"Name":"Joe",
"Last":"Doe",
"Client":{
"ClientId":"1",
"Product":"Apple",
"Message":"Peter likes apples"
},
"Date":"2012-02-14"
}
]
}
If we build a data structure that can hold that definition, it would be something like:
public class Root
{
public List<Profile> Profile { get; set; }
}
public class Profile
{
public string Name { get; set; }
public string Last { get; set; }
public Client Client { get; set; }
public string Date { get; set; }
}
public class Client
{
public string ClientId { get; set; }
public string Product { get; set; }
public string Message { get; set; }
}
Now, and finally the answer to how to deserialize a json string into a particular object without third party libraries:
Root root = JsonSerializer.Deserialize<Root>(json);
Where json is the variable that contains your json string.
I add another link of interest, the official documentation of the Deserialize(...) method: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer.deserialize
Something that is really useful is the exception that can be thrown, JsonException: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonexception
DataContractJsonSerializer does the job, but it uses more sophisticated format for DateTime serialization.

Categories

Resources