C#: How to parse HttpWebResponse object? - c#

I can explain this question better in terms of code and example. This is my code so far:
url = "x";
// create the request
req = WebRequest.CreateHttp(url);
req.ClientCertificates.Add(Program.GetCert(thumbprint));
result = (HttpWebResponse)req.GetResponse();
using (Stream data = result.GetResponseStream())
{
if (data != null)
{
TextReader tr = new StreamReader(data);
json = tr.ReadToEnd();
}
}
System.Diagnostics.Debug.WriteLine(json);
This is the output of the code:
{ "field1":"blah","field2":[
{
"Id":"1","Name":"Jon"
},{
"Id":"2","Name":"Mark"}] }
What I want to do-->
Access field2 of that json and iterate through ids and names (I don't care about field1 at all). How can I do that? Has this got anything to do with serialization?

one possible solution is -
var o = (JArray)(JObject.Parse(json)["field2"]);
foreach (JToken token in o)
{
Console.WriteLine(token["Id"]);
Console.WriteLine(token["Name"]);
}
Alternatively, you could create strongly typed C# objects and access them as a list -
static void Main(string[] args)
{
var o = JsonConvert.DeserializeObject<RootObject>(json).field2;// list - count = 2
}
public class Field2
{
public string Id { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public string field1 { get; set; }
public List<Field2> field2 { get; set; }
}

Use the DataContractJsonSerializer Class with suitable DataContract classes (Using Data Contracts), to deserialize your JSON data to objects.
Then you can iterate your way through the data.

First install Json.NET and try something like:
dynamic stuff = JObject.Parse(json);
var field2 = (JArray)stuff["field2"];
var field2Dict = field2.ToDictionary(k => (string)k["Id"], x => (string)x["Name"]);
foreach (var item in field2Dict)
{
System.Diagnostics.Debug.WriteLine("Id: {0} Nam: {1}", item.Key, item.Value);
}

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);

How can i access fields of anonymous typed JArray in C#?

string sampleString = "[{\"id\":\"1\",\"status\":302},{\"id\":\"2\",\"status\":302},{\"id\":\"3\",\"status\":302},{\"id\":\"4\",\"status\":302}]";
JArray json = JArray.Parse(sampleString );
TempValue t;
foreach(JObject obj in json)
{
t = new TempValue {
id =//id of json,
status=//state of json
};
}
i want to access value of json anonymous objec to assign to t object.
It is always good to work with a typed object to avoid typing mistakes. In this case create a class with the structure of the json string like so:
public class StatusObj
{
public string id { get; set; }
public int status { get; set; }
}
The deserialize the json string to list of your class like so:
List<StatusObj> obj = JsonConvert.DeserializeObject<List<StatusObj>>(sampleString);
And then you can loop through the list like so:
foreach (var item in obj)
{
var id = item.id;
var status = item.status;
}
The whole code look like this:
class Program
{
static void Main(string[] args)
{
string sampleString = "[{\"id\":\"1\",\"status\":302},{\"id\":\"2\",\"status\":302},{\"id\":\"3\",\"status\":302},{\"id\":\"4\",\"status\":302}]";
List<StatusObj> obj = JsonConvert.DeserializeObject<List<StatusObj>>(sampleString);
foreach (var item in obj)
{
var id = item.id;
var status = item.status;
}
}
}
public class StatusObj
{
public string id { get; set; }
public int status { get; set; }
}
NB. Newtonsoft.Json package needed to be installed. You can also convert any json to class here
By the indexer
foreach(JObject obj in json)
{
t = new TempValue {
id = obj["id"].ToString() ,
...
};
Object.Item Property (String)
Gets or sets the JToken with the specified property name.

C# Deserialization of JSON for use in a foreach loop

I have json that is posted from a HTTP req. I am trying to deserialize it for use in a for each loop. Unfortunately, its format is kicking my ass as its a list of objects (i believe).
so far i have the following:
dynamic jsonObj = JsonConvert.DeserializeObject(await req.ReadAsStringAsync());
foreach (var p in jsonObj.hireSchedules)
{
///do something
}
My json is as below:
{
"hireSchedules": [
{
"plant": "7246054",
"num" : "79",
"hire": "1137277"
},
{
"plant": "7246055",
"num" : "80",
"hire": "1137278"
}
]
}
I have the following classes:
public class HireSchedule
{
public string plant { get; set; }
public string num { get; set; }
public string hire { get; set; }
}
public class RootObject
{
public List<HireSchedule> hireSchedules { get; set; }
}
Any help would be appreciated. Thanks!
Since you have already defined the classes it's easy enough to deserialize it into them. Then you have a strongly typed class and the IDE should be able to help you out how to access the properties.
var json = File.ReadAllText("json1.json");
var root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (var p in root.hireSchedules)
{
///do something
}
One of the way is to use Newtonsoft.json nuget which is really very powerful, so
var files = JObject.Parse(YourJSON);
var recList = files.SelectTokens("$..hireSchedules").ToList();
foreach (JObject obj in recList.Children())
{
foreach (JProperty prop in obj.Children())
{
var key = prop.Name.ToString();
var value = prop.Value.ToString();
//Do your stuffs here
}
}

how to assign JSON array of object data to appropriate list of T

I have two types SalesData and CollectionData. These two types are entirely different type. So when I passed the data to front end i created dynamic data type and passed the data to front end depending on the call.
While receiving data back, I created json data which is array of objects.
Now I am in situation how do i assigned incoming arrays to List or List according to the type.
This is what I have done.
public ActionResult DownloadDataInExcel(List<object>data, int type)
{
if (type == (int)MyEnum.Sales)
{
var mycontacts = JsonConvert.DeserializeObject<List<SalesData>>(data.ToString());
foreach (var item in mycontacts)
{
System.Diagnostics.Debug.WriteLine($"{item.Name}-{item.City}-{item.Country}");
}
}else
{
var mycontacts = JsonConvert.DeserializeObject<List<CollectionData>>(data.ToString());
foreach (var item in mycontacts)
{
System.Diagnostics.Debug.WriteLine($"{item.Name}-{item.City}-{item.Country}");
}
}
//to do: Convert data to Excel File
throw new NotImplementedException();
}
1) You need a generic method to deserialize your incoming json to appropriate List<> object
public static List<T> DeserializeList<T>(string json)
{
return JsonConvert.DeserializeObject<List<T>>(json);
}
2) Here I create an console app for your demonstration purpose.
class Program
{
static void Main(string[] args)
{
string json1 = #"[{'Id1':'1','Name1':'Mike','Age1':43},{'Id1':'2','Name1':'Anna','Age1':56}]";
string json2 = #"[{'Id2':'1','Name2':'Mike','Age2':43},{'Id2':'2','Name2':'Anna','Age2':56}]";
//Pass json1 and deserialize into list of Sample1
var sample1List = DeserializeList<Sample1>(json1);
sample1List.ForEach(x => Console.WriteLine($"Id1: {x.Id1}, Name1: {x.Name1}, Age1: {x.Age1}"));
Console.WriteLine("\n");
//Pass json2 and deserialize into list of Sample2
var sample2List = DeserializeList<Sample2>(json2);
sample2List.ForEach(x => Console.WriteLine($"Id2: {x.Id2}, Name2: {x.Name2}, Age2: {x.Age2}"));
Console.ReadLine();
}
public static List<T> DeserializeList<T>(string json)
{
return JsonConvert.DeserializeObject<List<T>>(json);
}
}
class Sample1
{
public string Id1 { get; set; }
public string Name1 { get; set; }
public int Age1 { get; set; }
}
class Sample2
{
public string Id2 { get; set; }
public string Name2 { get; set; }
public int Age2 { get; set; }
}
Output:
You can use try-catch
try
{
var someresult = JsonConvert.DeserializeObject<Type1>(data.ToString());
// data was Type1 indeed, deal with Type1
}
catch{}
try
{
var someresult = JsonConvert.DeserializeObject<Type2>(data.ToString());
// data was Type2 indeed, deal with Type2
}
catch{}

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

Categories