Deserializing JSON to Object - c#

I'm receiving JSON, that i need to Deserialize. I'm using JavaScriptSerializer to do so.
E.g. Objects
class Player
{
public string name{ set; get; }
public float yPos { set; get; }
public float xPos { set; get; }
}
class Communication
{
public string id{ set; get; }
public string message{ set; get; }
public string status{ set; get; }
}
E.g. JSONs:
var json1 = "[{\"name\":\"Master\",\"xPos\":\"34.67\",\"yPos\":\"85.36\"}, {\"name\":\"Puppet\",\"xPos\":\"19.56\",\"yPos\":\"75.19\"}]";
var json2 = "[{\"id\":\"5697862\",\"message\":\"Hello\",\"status\":\"85.36\"}, {\"id\":\"4698458\",\"message\":\"Hi\",\"status\":\"75.19\"}]";
Deserializer Method:
private static List<T> Deserialize<T>(string json)
{
var s = new System.Web.Script.Serialization.JavaScriptSerializer();
List<T> obj = s.Deserialize<List<T>>(json);
return obj;
}
But here is the problem I have two different kind of JSON messages coming. So how do I figure out to what object I need to Deserialize?

Instead of deserializing to a specific class you can process the result dynamically
var js = new JavaScriptSerializer();
dynamic dynObj = js.DeserializeObject(jsonN);
foreach (var obj in dynObj)
{
if (obj.ContainsKey("name")) Console.WriteLine(obj["name"]);
else Console.WriteLine(obj["message"]);
}

I would recommend taking a look at the DataContractJsonSerializer (which can also deserialize). This class ensures that you are following the specific contract when you serialize and deserialize to and from JSON, respectively.
For deserialization, it works something like this:
stream1.Position = 0;
Person p2 = (Person)ser.ReadObject(stream1);
Serialization works like this:
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
ser.WriteObject(stream1, p);
See the link for additional explanation.

Related

Parse JSON String into List

It is needed to parse JSONString into List. (List of instances)
I'm trying to use JSON.NET by Newtonsoft.
I have classes:
public class Item
{
public int ID { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Manufactorers { get; set; }
}
The JSON string looks something like this:
[
{
"Column0":23.0,
"Column1":"Евроен",
"Column2":"https://www.123.com",
"Column3":"Фак"
},
{
"Column0":24.0,
"Column1":"Еил",
"Column2":"https://www.123.com",
"Column3":"Старт"
}
]
I've been trying to do something like this:
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(result);
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(JSONString);
But it returns 0 and null.
I have no idea, how to fix it.
Also here I truy to parse Excel file. This code works, but after deserialization, I have just 0 and null.
var filePath = #"..\..\..\..\doc.xlsx";
using (var steam = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(steam))
{
var result = reader.AsDataSet().Tables["Лист1"];
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(result);
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(JSONString);
}
}
The naming of JSON and your class does not match. This can be fixed using JsonProperty attributes:
[JsonProperty("Column0")]
public decimal ID { get; set; }
Second, JSON deserizlizer can not deserialize string "23.0" to int when there is decimal point. You can retype ID to decimal or double to make it work.
Little test here:
public class TestClass
{
[JsonProperty("Column0")]
public decimal ID { get; set; }
}
Then the deserialization works without errors:
var testClassJson = "{\"Column0\": 12.0}";
var i = JsonConvert.DeserializeObject<TestClass>(testClassJson);

BSon Exception newtonsoft.json

Given
public class Something
{
[JsonProperty(PropertyName = "Ver")]
public string ver { get; set; }
[JsonProperty(PropertyName = "SomethingElse")]
public object somethingElse { get; set; } // will blow up
// public SomethingElse somethingElse { get; set; } // will not
}
public class SomethingElse
{
[JsonProperty(PropertyName = "uuid")]
public Guid uuid { get; set; }
}
Attempting to serialize then deserialize Something will throw Unable cast object of type Guid to Byte[] exception if the member somethingelse of something is an object rather than the type itself.
Sorry for the lack of details. Above was a simplified class that you can serialize but cannot deserialize the object. Below matches are situation more closely, only difference is the dictionary we need is , that will fail as well in the exact same manner. The example works with JSOn, not BSON. The serialization appears valid, just the deserialization throws an exception in the JSonWriter Unable to cast object of type 'System.Guid' to type 'System.Byte[]',line 552
case JsonToken.Bytes:
WriteValue((byte[])reader.Value);<-- is trying to case a Guid to byte array
break;
static void Main(string[] args)
{
const string path = #"C:\zzz_bson.dat";
WriteBson(path);
ReadBson(path);
}
private static void ReadBson(string path)
{
var jsonSerializer = new JsonSerializer();
var file = File.OpenRead(path);
var binaryReader = new BinaryReader(file);
var bsonReader = new BsonReader(binaryReader);
var something = jsonSerializer.Deserialize(bsonReader);
file.Close();
}
private static void WriteBson(string path)
{
//var something = new Dictionary<string, Guid> { { "uuid", new Guid("8afbc8b8-5449-4c70-abd4-3e07046d0f61") } }; //fails
var something = new Dictionary<string, string> { { "uuid", new Guid("8afbc8b8-5449-4c70-abd4-3e07046d0f61").ToString() } }; // works
var jsonSerializer = new JsonSerializer();
var file = File.OpenWrite(path);
var binaryWriter = new BinaryWriter(file);
var bsonWriter = new BsonWriter(binaryWriter);
jsonSerializer.Serialize(bsonWriter, something);
file.Close();
}

Deserialize a restful uri

I'm trying to deserialize a rest uri located at http://ws.geonames.org/countryInfo?lang=it&country=DE and keep getting error (There is an error in XML document (1, 1)). Plug http://ws.geonames.org/countryInfo?lang=it&country=DE into the browser and you can see the result.
I have a class
public class Country
{
public string CountryName {get;set;}
public string CountryCode {get;set;}
}
and the method in my console app is as follows:
static void DeserializeTheXML()
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "countryName";
xRoot.IsNullable = true;
XmlSerializer ser = new XmlSerializer(typeof(Country), xRoot);
XmlReader xRdr = XmlReader.Create(new StringReader("http://ws.geonames.org/countryInfo?lang=it&country=DE"));
Country tvd = new Country();
tvd = (Country)ser.Deserialize(xRdr);
Console.WriteLine("Country Name = " + tvd.CountryName);
Console.ReadKey();
}
any ideas on how to deserialize this rest service? thanks..
For serialization to work successfully you need to decorate your objects with the proper serialization attributes or use the XmlAttributeOverrides constructor. Also don't forget that XML is case sensitive and your objects must reflect the XML structure you are deserializing:
public class GeoNames
{
[XmlElement("country")]
public Country[] Countries { get; set; }
}
public class Country
{
[XmlElement("countryName")]
public string CountryName { get; set; }
[XmlElement("countryCode")]
public string CountryCode { get; set; }
}
class Program
{
static void Main()
{
var url = "http://ws.geonames.org/countryInfo?lang=it&country=DE";
var serializer = new XmlSerializer(typeof(GeoNames), new XmlRootAttribute("geonames"));
using (var client = new WebClient())
using (var stream = client.OpenRead(url))
{
var geoNames = (GeoNames)serializer.Deserialize(stream);
foreach (var country in geoNames.Countries)
{
Console.WriteLine(
"code: {0}, name: {1}",
country.CountryCode,
country.CountryName
);
}
}
}
}

Deserializing Json using .Net

I have an external vendor API that returns JSON in this format
{"3":{"id":1,"name":"Scott Foo","age":55},
"59":{"id":2,"name":"Jim Morris","age":62}}
I am trying to deserialize it using the following code
[DataContract]
public class Name
{
[DataMember]
public int id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public int age{ get; set; }
}
Code to deserialize is
List<Name> nameList = Deserialize<List<Name>>(temp);
where the Deserialize is defined as
public static T Deserialize<T>(string json)
{
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
ms.Dispose();
return obj;
}
The object returned in nameList is of zero count. Any idea how this JSON can be deserialized in .Net (i.e. not using Json.Net or any such third-party dll)?
Here is one option.
//using System.Runtime.Serialization.Json;
public static dynamic Deserialize(string content)
{
return new System.Web.Script.Serialization.JavaScriptSerializer().DeserializeObject(content);
}
var f = Deserialize(json);
List<Name> list = new List<Name>();
foreach(var item1 in (Dictionary<string, object>) f)
{
Dictionary<string, object> item2 = (Dictionary<string, object>) item1.Value;
list.Add( new Name(){
id = (int) item2["id"],
name = (string) item2["name"],
age = (int) item2["age"]
});
}
Your root object theoretically would be something like this
public class root
{
public Name 3;
public Name 59;
}
But 3 and 59 are not valid c# variable/field/property names (they are also dynamic). Therefore, you can not deserialize it to a class.
I see that you don't want to use Json.Net or any such third party dlls but this is how I parsed it using Json.Net
string json = #"{""3"":{""id"":1,""name"":""Scott Foo"",""age"":55},""59"":{""id"":2,""name"":""Jim Morris"",""age"":62}}";
JObject jobj = (JObject)JsonConvert.DeserializeObject(json);
foreach (JProperty user in jobj.Children())
{
Console.WriteLine(user.Name + "==>" + user.Value["name"]);
}
and the output
3==>Scott Foo
59==>Jim Morris

How to get JSON String value?

var responseFromServer =
// lines split for readability
"{\"flag\":true,\"message\":\"\",\"result\":{\"ServicePermission\":true,"
+ "\"UserGroupPermission\":true}}";
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var responseValue = serializer.DeserializeObject(responseFromServer);
responseFromServer value is get a webservice, and then how to get the JSON string value, such as "flag","Servicepermission"??
affix: i'm sorry, using c# to do this.
Note: The JavaScriptSerializer is actually the slowest JSON Serializer I've ever benchmarked. So much so I've had to remove it from my benchmarks because it was taking too long (>100x slower).
Anyway this easily solved using ServiceStack.Text's JSON Serializer:
var response = JsonSerializer.DeserializeFromString<Dictionary<string,string>>(responseFromServer);
var permissions = JsonSerializer.DeserializeFromString<Dictionary<string,string>>(response["result"]);
Console.WriteLine(response["flag"] + ":" + permissions["ServicePermission"]);
For completeness this would also work with ServiceStack.Text.JsonSerializer:
public class Response
{
public bool flag { get; set; }
public string message { get; set; }
public Permisions result { get; set; }
}
public class Permisions
{
public bool ServicePermission { get; set; }
public bool UserGroupPermission { get; set; }
}
var response = JsonSerializer.DeserializeFromString<Response>(responseFromServer);
Console.WriteLine(response.flag + ":" + response.result.ServicePermission);
if u are using jQuery u can do this
var json=jQuery.parseJSON(responseFromServer);
//acess
alert(json.ServicePermission);
if you are asing microsoft ajax do this
var json=Sys.Serialization.JavaScriptSerializer.deserialize(responseFromServer,true);
//acess
alert(json.ServicePermission);
in c# like php i have'nt seen any method that converts json to object on the fly. To do conversions in c# you must first create a class for this.
For your case you can do like this
//define classes
public class Response
{
public bool flag { get; set; }
public string message { get; set; }
public Permisions result { get; set; }
}
public class Permisions
{
public bool ServicePermission { get; set; }
public bool UserGroupPermission { get; set; }
}
var responseFromServer =
// lines split for readability
"{\"flag\":true,\"message\":\"\",\"result\":{\"ServicePermission\":true,"
+ "\"UserGroupPermission\":true}}";
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var responseValue = serializer.Deserialize<Response>(responseFromServer);
//access
responseValue.result.ServicePermission

Categories