Deserializing JSON result with Json & JavaScriptSerializer - c#

here's my problem:
I'm trying to deserialize json that hasn't been done by me. The format of the json is as follows:
{"responseId":1200,
"availableHotels":[
{"processId":"HA-84665605","hotelCode":"UKKTLT","availabilityStatus":"InstantConfirmation",...},
{"processId":"HA-28600965","hotelCode":"UKKTLT","availabilityStatus":"InstantConfirmation",...},
{"processId":"HI-63991185","hotelCode":"UKJOVF","availabilityStatus":"InstantConfirmation",...}
],
"totalFound":9,
"searchId":"TP-84026455"}
And the following classes:
getAvailableHotelResponse w/properties:
hotelObj availableHotels
int totalFound
String responseId
String searchId
hotelObj w/properties:
hotel hotel
hotel w/properties:
processId
hotelCode
availabilityStatus
...
Therefore, what I know I can tell from looking at the json is that it contains information of a getAvailableHotelResponse object.
So, I tried the following using JsonConvert and JavaScriptSerializer:
JavaScriptSerializer ser = new JavaScriptSerializer();
getAvailableHotelResponse availableResponse = ser.Deserialize<getAvailableHotelResponse>(json);
// Exception: "Type 'com.hotelspro.api.getAvailableHotelResponse' is not supported for deserialization of an array"
List<getAvailableHotelResponse> items = ser.Deserialize<List<getAvailableHotelResponse>>(json);
// items.Count = 0
List<getAvailableHotelResponse> result = JsonConvert.DeserializeObject<List<getAvailableHotelResponse>>(json);
// Exception: "Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[com.hotelspro.api.getAvailableHotelResponse]'."
getAvailableHotelResponse result2 = JsonConvert.DeserializeObject<getAvailableHotelResponse>(json);
// Exception: Cannot deserialize JSON array into type 'com.hotelspro.api.hotelObj'.
What's the correct sentence in order to deserialize this object?
Thanks!

It's difficult to interpret the structure of your objects based on your description but I was able to deserialize your sample JSON using the following minimal code:
var result = JsonConvert.DeserializeObject<getAvailableHotelResponse>(json);
public class getAvailableHotelResponse
{
public int responseId;
public availableHotel[] availableHotels;
public int totalFound;
public string searchId;
}
public class availableHotel
{
public string processId;
public string hotelCode;
public string availabilityStatus;
}

Neither of the above listed Objects fully match the JSON schema... Are you sure whoever serialized the object to JSON used any of those classes you're trying to deserialize to? If not, just create a class that you deserialize the JSON to:
public class HotelSearchResponse
{
public int responseID {get;set;}
public hotel[] availableHotels {get;set;}
public int totalFound {get;set;}
public string searchId {get;set;}
}
If the hotel array doesn't work, try List<hotel> instead for availableHotels type.
P.S. The closest object to the JSON from the ones listed in your question is getAvailableHotelResponse but it declares availableHotels as single hotel instace, instead the JSON has an array of hotel objects returned.

Related

Deserialize raw JSON and convert to custom C# Object

I have the following raw JSON string:
[\"Hello World!\",\"94952923696694934\",\"MyChannel\"]
I have tried the following without luck:
My custom object class:
public class MyObject
{
public string msg { get; set; }
public string id { get; set; }
public string chn { get; set; }
}
JSON string:
string str = "[\"Hello World!\",\"94952923696694934\",\"MyChannel\"]";
1st attempt at deserilization using System.Web.Script.Serialization:
JavaScriptSerializer serializer = new JavaScriptSerializer();
MyObject obj1 = serializer.Deserialize<MyObject>(str);
2nd attempt at deserilization using Newtonsoft.Json:
MyObject obj2 = JsonConvert.DeserializeObject<MyObject>(str);
Both attempts fail. Any suggestions?
You have a JSON array of strings, not an object with property names.
So the best you can do here is to deserialize the array:
IEnumerable<string> strings =
JsonConvert.DeserializeObject<IEnumerable<string>>(str);
...then use the resulting sequence strings as you see fit.
With PubNub, you can just pass in the native String, Dictionary, or Array, and we'll JSON encode it for you on the publish side, and auto JSON decode for you on the subscriber side.
It's because your 'custom object' isn't equivalent to the json representation. The json you're deserializing is just a string[] in C# (you can also use List<string> or other IEums).
So in code you're looking for;
string[] theJson = JsonConvert.DeserializeObject<string[]>(str);
MyObject would be used for the following json;
{
"msg":"Hello World!",
"id":"94952923696694934",
"chn":"MyChannel"
}

How to convert JSON Response to a List in C#?

This might be a basic question but I am stuck while converting a JSON Response to a List.
I am getting the JSON Response as,
{"data":[{"ID":"1","Name":"ABC"},{"ID":"2","Name":"DEF"}]}
Have defined a Class,
class Details
{
public List<Company> data { get; set; }
}
class Company
{
public string ID { get; set; }
public string Name { get; set; }
}
Have tried this for converting,
List<Details> obj=List<Details>)JsonConvert.DeserializeObject
(responseString, typeof(List<Details>));
But this returns an error, saying
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Client.Details]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Kindly help!
You don't have a List<Detail> defined in your JSON. Your JSON defines one Detail record, which itself has a list of companies.
Just deserialize using Details as the type, not List<Details> (or, if possible, make the JSON wrap the single detail record into a one item array).
You need to Deserialize like this:
var Jsonobject = JsonConvert.DeserializeObject<Details>(json);
using classes generated by json2csharp.com:
var Jsonobject = JsonConvert.DeserializeObject<RootObject>(json);
and your classes should be :
public class Datum
{
public string ID { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
}
you can always use json2csharp.com to generate right classes for the json.
You can use JavaScriptDeserializer class
string json = #"{""data"":[{""ID"":""1"",""Name"":""ABC""},{""ID"":""2"",""Name"":""DEF""}]}";
Details details = new JavaScriptSerializer().Deserialize<Details>(json);
EDIT: yes, there's nothing wrong with OP's approach, and Servy's answer is correct. You should deserialize not as the List of objects but as the type that contains that List

How to convert a Json string to a class that has a list in Json.Net with C# when the json has an array one level deeper

I have a C# Application in which I am using Json.Net from Nuget.
I get a json from my server which I need to convert into a C# object and with a few modifications I will send it back to the server as json.
Here's my model in C# (which I got after converting the server xsd)
public class Tags
{
public List<Tag> tagData { get; set; }
}
public class Tag
{
public string name {get; set;}
}
Here's my JSON string that is obtained from the server and an attempt at conversion to my model
//Json string obtained from server (hardcoded here for simplicity)
string json = "{tagData: {tags : [ { name : \"John\"}, { name : \"Sherlock\"}]}}";
//An attempt at conversion
var output = JsonConvert.DeserializeObject<Tags>(json);
This is the exception I get with the above code
An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[jsonnetExample.Tag]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'tagData.tags', line 1, position 17.
After understanding the above message I tried the following 2 things in the hope of fixing it.
A.I tried putting a JsonProperty to my first model.
[JsonProperty(PropertyName = "tags")]
This didn't throw the exception anymore but the output tagData was null.
B. I modified my model as follows
public class Tags
{
public WrapTag tagData { get; set; }
}
public class WrapTag
{
public List<Tag> tags { get; set; }
}
public class Tag
{
public string name {get; set;}
}
This didn't throw any exception and populated the objects as expected. But Now I lost the one to one mapping between xsd(classes from the server) to my client model classes. Is it possible to get this deserialization working without the creation of the WrapTag class?
I would be very glad if someone can point me in the right direction.
Thanks in advance.
Here's one option, using JObject.Parse:
string json = "{tagData: {tags : [ { name : \"John\"}, { name : \"Sherlock\"}]}}";
List<Tag> tagList = JObject.Parse(json)["tagData"]["tags"].ToObject<List<Tag>>();
// or:
// List<Tag> tagList = JObject.Parse(json).SelectToken("tagData.tags")
// .ToObject<List<Tag>>();
Tags tags = new Tags { tagData = tagList };

Deserialize JSON data

I've got a JSON data from Twitter API SEARCH.
I'm trying to deserialize these data into objects.
The JSON scheme looks like this:
{
"element": INT,
"element2": STRING,
..
..
"Results":[
{
"user":STRING,
"image":STRING,
..
..
}
]
}
How could I deserialize those JSON elements into objects using JSON Toolkit or something else?
Create a class that matches the JSON schema
public class Data
{
public string Element{get;set;}
public string Element2{get;set;}
public List<Result> Results{get;set;}
}
public class Result
{
public string User{get;set;}
public string Image{get;set;}
}
and use JSON.NET to deserialize
var result = JsonConvert.DeserializeObject<Result>(json);
If you have problems with correct type definition, you can always use dynamic deserialization using Json.Net:
var original = JsonConvert.DeserializeObject<dynamic>(jsonstring);
and then build your desired object based on it (if for example the original one contains overhead information set, and you don't need all of them):
var somepart = new {
E1 = original.element1,
E2 = original.element2
};

Deserializing Json with numbered keys in ServiceStack

I have such Json:
{
data:{
"50":{"id":"50","name":"test", etc...},
"51":{"id":"51","name":"test", etc...},
"53":{"id":"53","name":"test", etc...},
...
}
}
What is the correct way to deserialize this Json?
[UPDATED]
I think I must to adjust my question. Is it possible to parse Json using class with description of objects. E.g. I have such class and Json which I parse with .FromJson():
public class Data
{
public ...
}
public class Category
{
public int Id{get;set;}
public string Name{get;set;}
}
What should be instead three dots?
Your json contains an object O. This object has a member data that is a dictionary from strings or ints to your category objects. So try something like:
class Root
{
public Dictionary<int, Category> data;
}
var o = JavaScriptSerializer.Deserialize<Root>(json);
If you are using servicestack.text just do
var v = myJson.FromJson();
Don't forget that servicestack is best used when serialization also made with servicestack.
the best way to deserialize Json object to c# class in JSON.NET project (found on codeplex)
the deserialize example is:
JsonConvert.DeserializeObject<Category>(jsonString);

Categories