Deserialize json dictionary to c# - c#

I'm getting this json from an API.
string json = "{'serviceSession':{ '123123123':[{'apn':'abc'},{'apn':'bcd'},{'apn':'def'}]}}";
When I'm trying to deserialize it with
public class ServiceSession
{
public Dictionary<string, List<ServiceSessionType>> ServiceSessions { get; set; }
}
public class ServiceSessionType
{
public string Apn { get; set; }
}
and
var test = JsonConvert.DeserializeObject<ServiceSession> (json);
I'm getting null.
What's wrong? any ideas?
Thank you in advance!!

There is a missmatch between the datastructure and the json string. You need to change:
public class ServiceSession
{
//ServiceSessions replaced by serviceSession
public Dictionary<string, List<ServiceSessionType>> serviceSession { get; set; }
}
Another solution is to add a DataMember attribute which tells the deserializer the name.
[System.Runtime.Serialization.DataContract]
public class ServiceSession
{
[System.Runtime.Serialization.DataMember(Name = "serviceSession")]
public Dictionary<string, List<ServiceSessionType>> ServiceSessions { get; set; }
}
This makes sense if you can't change the class or the name is a keyword in C#.

Related

How would you model a json in c#

I have a JSON like
{
"myObject":{
"Difficult": true,
"Impossible": false
}
}
and a model like
public class Blas
{
public string something { get; set; }
public int somethinElse { get; set; }
public Dictionary<string, bool> myObject{ get; set; } //this is how I'm currently modeling the JSON
}
and when I use it I'm doing myObject["Difficult"];
but I need to do something like if(myObject.Difficult)..
Note to duplicate suggestion: The suggestion is
irrelevant because as the title says, my question is regarding to
model a JSON in C#, not converting. I can convert, but I need to
improve my current modeling in c#.
add class "MyObject" like this
Import
using Newtonsoft.Json
Code
public class MyObject
{
[JsonProperty("Difficult")]
public bool Difficult { get; set; }
[JsonProperty("Impossible")]
public bool Impossible { get; set; }
}
public class MyData {
[JsonProperty("myObject")]
public MyObject { get; set; }
}
then, define class like this
MyData obj = JsonConvert.DeserializeObject<MyData>(jsonString);
jsonString would be your json string.

parsing Json with weird attribute names [duplicate]

How can we parse if json fields contains a colon(:)? Like this:
{
"dc:creator":"Jordan, Micheal",
"element:publicationName":"Applied Ergonomics",
"element:issn":"2839749823"
}
In fact I wonder how to do this with a library like restsharp, for mapping?
Using Json.Net
string json = #"{
""dc:creator"":""Jordan, Micheal"",
""element:publicationName"":""Applied Ergonomics"",
""element:issn"":""2839749823""
}";
var pub = JsonConvert.DeserializeObject<Publication>(json);
public class Publication
{
[JsonProperty("dc:creator")]
public string creator { set; get; }
[JsonProperty("element:publicationName")]
public string publicationName { set; get; }
[JsonProperty("element:issn")]
public string issn { set; get; }
}
OR
Console.WriteLine(JObject.Parse(json)["dc:creator"]);
If you use DataContractJsonSerializer, DataMemberAttribute has property Name which can be used to override default name. This means that when you deserialize json value of property dc:creator is assigned to Publication::Creator property and on the contrary when you serialize C# object.
For example:
public class Publication
{
[DataMember(Name="dc:creator")]
public string Creator { set; get; }
[DataMember(Name="element:publicationName")]
public string PublicationName { set; get; }
[DataMember(Name="element:issn")]
public string Issn { set; get; }
}
If you choose to use Json.Net, #L.B's answer is the way to go.

Newtonsoft.Json Custom Root Name for Deserialization

I have this class that defines the json format:
public class ResultType
{
public bool status { get; set; }
public string message { get; set; }
}
The actual json looks like this:
{"result":{"status":true,"message":"Success"}}
How can I override the root attribute when de-serializing the json to "result"
JObject jsonResponse = JObject.Parse(jsonString);
ResultType _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultType>(jsonResponse["result"].ToString());
Console.WriteLine(_Data.status);
Fiddle: https://dotnetfiddle.net/gjYS2p
I have a central deserialization method, so I'm trying to avoid type specific code as much as possible.
I used the following to resolve the problem, maybe not as sexy as I was hoping for but it works.
public class ResultType
{
public ResultDetailType result { get; set; }
}
public class ResultDetailType
{
public bool status { get; set; }
public string message { get; set; }
}

Deserialize JSON with variable name arrays

I am getting JSON that is being returned from a REST web service for survey responses. It has arrays for the name portion of some of the name value pairs. Additionally the names will be variable depending on the type of questions asked. I'm using JSON.net and trying to deserialize the returned value into some type of object tree that I can walk but can't figure out what structure to use to have it filled in.
I tested the following snippet in LinqPad and fields is always empty. Is there someway to easily read in the variable data or do I have to parse it in code?
void Main() {
string json = #"{
'result_ok':true,
'total_count':'51',
'data':[{
'id':'1',
'status':'Deleted',
'datesubmitted':'2015-01-12 10:43:47',
'[question(3)]':'Red',
'[question(4)]':'Blue',
'[question(18)]':12,
'[variable(\'STANDARD_IP\')]':'127.0.0.1',
'[variable(\'STANDARD_GEOCOUNTRY\')]':'United States'
}]
}";
var responses = JsonConvert.DeserializeObject<RootObject>(json);
responses.Dump();
}
public class RootObject {
public bool result_ok { get; set; }
public string total_count { get; set; }
public List<Response> data { get; set; }
}
public class Response {
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
public List<object> fields = new List<object>();
}
Change the fields property in your Response class to be a Dictionary<string, object>, then mark it with a [JsonExtensionData] attribute like this:
public class Response
{
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
[JsonExtensionData]
public Dictionary<string, object> fields { get; set; }
}
All of the fields with the strange property names will then be placed into the dictionary where you can access them as normal. No extra code is required.
Here is a demo: https://dotnetfiddle.net/1rQUXT

parsing nested (I think) JSON

I've been trying to parse this JSON string. I'm using JSON.NET and a snippet of the JSON, my classes and basic function calls follow:
{"status":"ok","apirate":"0","people":{
"Mike":{"id":"Mike","rating":"0.80","questions":"100"},
"Donald":{"id":"Donald","rating":"0.7","questions":"9"},
"Tony":{"id":"Tony","rating":"0.22","questions":"2"},
"Penelope":{"id":"Penelope","rating":"0.006","questions":"6"},
"Sarah":{"id":"Sarah","rating":"0.79","questions":"20"},
"Thomas":{"id":"Thomas","rating":"0.12","questions":"25"},
"Gail":{"id":"Gail","rating":"0.44","questions":"35"}}}
The classes I'm using as storage objects:
public class Folks
{
public Folks()
{
}
public String status;
public String message; //optional
public int apirate;
public PeopleDetails[] people;
}
public class PeopleDetails
{
public PeopleDetails ()
{
}
public String id;
public double rating;
public int questions;
}
And finally, what I'm doing in the code:
Folks test = new Folks();
test = JsonConvert.DeserializeObject<Folks>(myRequest.GetResponse());
Status and API rate are coming through fine, message doesn't exist because there's no error and my PeopleDetails array is making an exception. (EDIT: throwing a JsonSerializationException because the type requires a JSON array to deserialize correctly.) I've tried putting another class/object between the two I've pasted here and I've tried different collections, and so on.
So... since this is my first time working with this (smart, pick the complex stuff the first time) can anybody point me towards a solution?
Thanks in advance.
Well, first, your given JSON is incorrect, there is a { missing in the penelope record.
so the correct JSON would be
{"status":"ok","apirate":"0","people":{
"Mike":{"id":"Mike","rating":"0.80","questions":"100"},
"Donald":{"id":"Donald","rating":"0.7","questions":"9"},
"Tony":{"id":"Tony","rating":"0.22","questions":"2"},
"Penelope":{"id":"Penelope","rating":"0.006","questions":"6"},
"Sarah":{"id":"Sarah","rating":"0.79","questions":"20"},
"Thomas":{"id":"Thomas","rating":"0.12","questions":"25"},
"Gail":{"id":"Gail","rating":"0.44","questions":"35"}}}
Then, if you have a look at the structur, you may not that people is not a list but a dictionary, with the name as the key.
So, here is a working test
[TestMethod]
public void Test()
{
var json = "{\"status\":\"ok\",\"apirate\":\"0\",\"people\":{\n\"Mike\":{\"id\":\"Mike\",\"rating\":\"0.80\",\"questions\":\"100\"},\n\"Donald\":{\"id\":\"Donald\",\"rating\":\"0.7\",\"questions\":\"9\"},\n\"Tony\":{\"id\":\"Tony\",\"rating\":\"0.22\",\"questions\":\"2\"},\n\"Penelope\":{\"id\":\"Penelope\",\"rating\":\"0.006\",\"questions\":\"6\"},\n\"Sarah\":{\"id\":\"Sarah\",\"rating\":\"0.79\",\"questions\":\"20\"},\n\"Thomas\":{\"id\":\"Thomas\",\"rating\":\"0.12\",\"questions\":\"25\"},\n\"Gail\":{\"id\":\"Gail\",\"rating\":\"0.44\",\"questions\":\"35\"}}}";
var folks = JsonConvert.DeserializeObject<Folks>(json);
Assert.AreEqual("ok", folks.Status);
}
public class Folks
{
public Folks()
{
this.People = new Dictionary<string, PeopleDetails>();
}
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("apirate")]
public int Apirate { get; set; }
[JsonProperty("people")]
public Dictionary<string, PeopleDetails> People { get; set; }
}
public class PeopleDetails
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("rating")]
public decimal Rating { get; set; }
[JsonProperty("questions")]
public int Questions { get; set; }
}

Categories