Reputation: 689
I need to deserialize the following JSON:
"response": {
"records": {
"record-1": { "id": "1", "name": "foo" },
"record-2": { "id": "2", "name": "foo" },
"record-3": { "id": "3", "name": "foo-bar" }
}
}
I am using the following C# code to deserialize the above JSON:
HttpWebRequest httpWebRequest
= System.Net.WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse httpWebResponse
= httpWebRequest.GetResponse() as HttpWebResponse)
{
if (httpWebResponse.StatusCode != HttpStatusCode.OK)
throw new Exception(
string.Format("Server error (HTTP {0}: {1}).",
httpWebResponse.StatusCode,
httpWebResponse.StatusDescription)
);
Stream stream = httpWebResponse.GetResponseStream());
DataContractJsonSerializer dataContractJsonSerializer
= new DataContractJsonSerializer(typeof(MyResponseClass));
objResponse = dataContractJsonSerializer.ReadObject(stream);
if (objResponse == null)
return null;
}
And
[DataContract]
class MyResponseClass
{
[DataMember]
public Response response { get; set; }
}
[DataContract]
public class Response
{
[DataMember]
public Records records { get; set; }
}
[DataContract]
public class Records
{
[DataMember(Name = "record-1")]
Record record_1 { get; set; }
[DataMember(Name = "record-2")]
Record record_2 { get; set; }
[DataMember(Name = "record-3")]
Record record_3 { get; set; }
}
[DataContract]
public class Record
{
[DataMember]
public string id { get; set; }
[DataMember]
public string name { get; set; }
}
Surely there is a better way to get hold of the array of "record" under "records" that makes this scalable instread of defining each record individualy in the code. I know that a JSON reader can be used, but would prefer a simple deserialze routine.
I want to be able to deserialize the JSON into a list of records (e.g. List, how do I achieve this?
Upvotes: 0
Views: 186
Reputation: 498
Solution is simple your json format
{
"response": {
"records": {
"record-1": { "id": "1", "name": "foo"},
"record-2": { "id": "2", "name": "foo"},
"record-3": { "id": "3", "name": "foo-bar"}
}
}
}
can be parsed with json.net in a simple and powerfull way with this code
var recordsJson = jsonObject.SelectToken("response")
.SelectToken("records")
.Children<JProperty>()
.Select(p=>p.Value)
.ToList();
foreach (var rec in recordsJson)
{
var record = JsonConvert.DeserializeObject<Record>(rec.ToString());
Records.Add(record);
}
We get all the records into a jobject list then parse each of them in the simplest way ever and add each record to a list
Upvotes: 0
Reputation: 689
MyResponse myResponse = null;
HttpWebRequest httpWebRequest = System.Net.WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse)
{
if (httpWebResponse.StatusCode != HttpStatusCode.OK)
throw new Exception(string.Format("Server error (HTTP {0}: {1}).", httpWebResponse.StatusCode, httpWebResponse.StatusDescription));
Stream stream = httpWebResponse.GetResponseStream());
using (StreamReader streamReader = new StreamReader(stream))
{
myResponse = JsonConvert.DeserializeObject<MyResponse>(streamReader.ReadToEnd());
}
}
return myResponse;
[DataContract]
class MyResponseClass
{
[DataMember]
public Response response { get; set; }
}
[DataContract]
public class Response
{
[DataMember(Name = "records")]
public IDictionary<string, Record> Records { get; set; }
}
[DataContract]
public class Record
{
[DataMember]
public string id { get; set; }
[DataMember]
public string name { get; set; }
}
Upvotes: 0
Reputation: 2786
I think in you case it would be better to remove Records
class at all and and in Response
class change type of Records
property to IDictionary<string, Record>
. So your class structure might look like that:
[DataContract]
class MyResponseClass
{
[DataMember(Name = "response")]
public Response Response { get; set; }
}
[DataContract]
public class Response
{
[DataMember(Name = "records")]
public IDictionary<string, Record> Records { get; set; }
}
[DataContract]
public class Record
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
}
You can always think of JSON as IDictionary<string, object>
in C#. It makes understanding of JSON much easier.
I also suggest to use Name
property of DataMember
attribute because you can keep C# property naming according to guidelines.
Upvotes: 1