How to add a property data: for json? - c#

I've created a list of object in C# but I'm struggling to understand how I can add a property (that may not be the right term) to the beginning of it:
This might be really obvious and I'm not sure what I need to Google! Any help would be appreciated!
What I'm trying to do:
{
'data' : [ <--Add this in (is this a property of the object?)
{
'valueName1': 'value1',
'valueName2': 'value2',
'valueName3': 'value3',
},
{
'valueName1': 'value1',
'valueName2': 'value2',
'valueName3': 'value3',
},
]}
What I've got currently!
[
{
'valueName1': 'value1',
'valueName2': 'value2',
'valueName3': 'value3',
},
{
'valueName1': 'value1',
'valueName2': 'value2',
'valueName3': 'value3',
},
]
This is what I've got in C# at the moment:
result= new List<TestList> { };
foreach (var issueData2 in myDeserializedClass.issues)
{
result.Add(new TestList { valueName1 = issueData2.fields.summary,
valuename2 = issueData2.fields.created,
valuename3 = issueData2.fields.updated, });
}
string jsonString = JsonConvert.SerializeObject(newtonresult);
With this class:
public class TestList
{
public String valuename1 { get; set; }
public String valuename2 { get; set; }
public String valuename3 { get; set; }
}

Please don't violate C# naming conventions (properties have PascalCaseNames) just to get your JSON to appear correctly; common json serializers support attributes that allow you to name your C# properties differently to json:
public class TestList
{
[JsonProperty("valuename1")]
public String ValueName1 { get; set; }
[JsonProperty("valuename2")]
public String ValueName2 { get; set; }
[JsonProperty("valuename1")]
public String ValueName3 { get; set; }
}
..that's if you even need to; you can usually also configure serializers so they produce camelCaseJsonPropertyNames even if the C# names are PascalCase - for example
And as GSerg comments, you can put your testlist list in another class:
public class Wrapper {
[JsonProperty("data")]
public List<TestList> Data { get; set;}
}
Then have a creation of:
result= new List<TestList> { };
foreach (var issueData2 in myDeserializedClass.issues)
{
result.Add(new TestList { valueName1 = issueData2.fields.summary,
valuename2 = issueData2.fields.created,
valuename3 = issueData2.fields.updated, });
}
var ser = new Wrapper { Data = result };
string jsonString = JsonConvert.SerializeObject(ser);
You actually don't even need the class Wrapper, if you want.. You can also use an anonymous type:
string jsonString = JsonConvert.SerializeObject(new{ data = result });

So, you basically want property data which is an array of object TestList class
public class Test{
public IEnumerable<TestList> data {get; set'}
}
Now you can serialize the data
string jsonString = JsonConvert.SerializeObject<Test>(newtonresult);

Related

how to pull out array of string values from a deserialized JSON response

I am pretty new to coding and here is my requirement:
I am getting a JSON response which has an array of values (refer read,update,delete in the below JSON response)
The number of values is dynamic and tend to vary each time.
I want to know how to retrieve them and put into an string array and return the values
Eg.: end result should be like
string[] deleteValues = {"MCS:Menu:Admin","MCS:test"}
In case if there is answer already available to this question, please point me in the right direction.
Thanks in advance
==========================================
I am able to get the values this way...
string value1 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[0].ToString();
string value2 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[1].ToString();
but since the number of values in delete is dynamic, i need to how to pull them.
====================
the code snippet:
string resp = new StreamReader(request1.GetResponse().GetResponseStream()).ReadToEnd(); // resp is a JSON response from a server
JSON_Deconstructor dc = new JSON_Deconstructor { };
dc.Permitted = new Permitted[1];
string value1 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[0].ToString();
string value2 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[1].ToString();
==================
JSON_Deconstructor class contents:
public class JSON_Deconstructor
{
public Permitted[] Permitted { get; set; }
public Denied[] Denied { get; set; }
}
==================
Permitted class contents:
public class Permitted
{
public string[] Read { get; set; }
public string[] Update { get; set; }
public string[] Delete { get; set; }
}
=================
JSON response:
{
"Permitted": [
{
"read": [
"MCS:Menu:Admin"
],
"update": [
"MCS:test"
],
"delete": [
"MCS:Menu:Admin",
"MCS:test"
]
}
]
}
First add jsonProperty to your class in order to be able to serialize.
public class Permitted
{
[JsonProperty("read")]
public string[] Read { get; set; }
[JsonProperty("update")]
public string[] Update { get; set; }
[JsonProperty("delete")]
public string[] Delete { get; set; }
}
//Response contains a list of permitted objects in Permitted property
public class PermittedResponse
{
public List<Permitted> Permitted { get; set; }
}
then in you method de serialize your response and loop through results to build your arrays.
List<string> deletedValues = new List<string>();
List<string> readValues = new List<string>();
List<string> updateValues = new List<string>();
PermittedResponse response = JsonConvert.DeserializeObject<PermittedResponse>(serializedJson);
response.Permitted.ForEach(e =>
{
deletedValues = deletedValues.Concat(e.Delete).ToList();
readValues = readValues.Concat(e.Read).ToList();
updateValues = updateValues.Concat(e.Update ).ToList();
});
Use Newtonsoft.Json. You can get it from NuGet. This is very simple and powerful library for Json.
Now, you should create a class, like:
public class Item
{
public List<string> MCS { get; set; } = new List<string>();
}
public class PermitedItem
{
public Item read {get; set;}
public Item update {get; set;}
public Item delete {get; set;}
}
public class MyResponse
{
public List<PermittedItem> Permitted = new List<PermittedItems>();
}
And then you use it like that:
MyResponse result = JsonConvert.DeserializeObject<MyResponse>(jsonAsString);
This should work.

write data from JSON in C#

I have JSON like this:
{
'surveys': [
{
'title': 'first',
'id': 100,
},
{
'title': 'second',
'id': 101,
},
{
'title': 'third',
'id': 102,
},
]
}
I want to have the output like this:
title: first
title: second
title: third
and my program in C# is like this:
WebClient client = new WebClient();
var json = client.DownloadString("http://www.test.com/api/surveys/?api_key=123");
Debug.WriteLine(json); //write all data from json
//add
var example = JsonConvert.DeserializeObject<Example>(json);
Debug.WriteLine(example.Data.Length);
class Example
{
public surveys[] Data { get; set; }
}
class surveys
{
public string title { get; set; }
public int id { get; set; }
}
I get this error:
Thrown: "Object reference not set to an instance of an object." (System.NullReferenceException) Exception Message = "Object reference not set to an instance of an object.", Exception Type = "System.NullReferenceException", Exception WinRT Data = ""
at this line: Debug.WriteLine(example.Data.Length);
where is the problem?
One problem I see is that your outer class has a property named Data, which is an array of 'surveys' objects, but your Json has a list of 'surverys' objects under the property 'surveys'. Hence the 'Data' property is never populated.
Consider the following C# class structure:
class Example
{
public survey[] surveys{ get; set; }//Data renames to surveys
}
class survey //Singular
{
public string title { get; set; }
public int id { get; set; }
}
Why can't you do so?:
JObject data = JObject.Parse(json);
foreach (var survey in data["surveys"].Children())
{
Debug.WriteLine("title: " + survey["title"]);
}
You need to use JSON.Net and use the class JsonConvert and the method DeserializeObject<T>.
If you run this:
JsonConvert.DeserializeObject<JObject>();
Then you will get back a list of de-serialized JObject objects.
Use, NuGet to download the package. I think it is called JSON.net.
Here is the weblink
WebClient client = new WebClient();
var json = client.DownloadString("http://www.test.com/api/surveys/?api_key=123");
Debug.WriteLine(json); //write all data from json
//add
var example = JsonConvert.DeserializeObject<Survey>(json);
Debug.WriteLine(example.length); // this could be count() instead.
class Survey
{
public string title { get; set; }
public int id { get; set; }
}
This should work!
Use json2csharp to generate c# classes from json.
You will also need to use Json.NET.
public class Survey
{
public string title { get; set; }
public int id { get; set; }
}
public class RootObject
{
public List<Survey> surveys { get; set; }
}
Then you can do:
var client = new WebClient();
string json = client.DownloadString(some_url);
RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (Survey s in root.surveys)
{
// Do something with your survey
}
Don't forget to use Newtonsoft.Json namespace once you add a reference to it within your project.
using Newtonsoft.Json;
Edit: I have tested it using:
string json = "{'surveys': [{'title': 'first','id': 100,},{'title': 'second','id': 101,},{'title': 'third','id': 102,},]}";
instead of using the WebClient, and it works.

json newtonsoft : Deserialize Object containing a list of string

I have the following issue with this json :
{
"EVTS": {
"EVT": [
{ "ID": "123456",
"KEY1" : "somekey",
"CATEG": [
"cat1",
"cat2",
"cat3"
]
}
]}
}
and this c# class:
public class myClass{
public string ID { get; set; }
public string KEY1 { get; set; }
public list<string> CATEG { get; set; }
}
public class ESObject1
{
[JsonProperty("EVT")]
public List<myClass> EVT { get; set; }
}
public class ESObject0
{
[JsonProperty("EVTS")]
public ESObject1 EVTS { get; set; }
}
}
here i call the deserializer :
ESObject0 globalobject = JsonConvert.DeserializeObject<ESObject0>(json);
But this last code doesnt work, i throws this exception : System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List1[System.String].`
Instead of list<string> i used string [] and only string nothing seems to work.
how can i deserialize this object correctly please.
Thank you.
There doesn't seem to be any apparent problem wit hyour code as this working example illustrates:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class myClass
{
public string ID { get; set; }
public string KEY1 { get; set; }
public List<string> CATEG { get; set; }
}
public class ESObject1
{
[JsonProperty("EVT")]
public List<myClass> EVT { get; set; }
}
public class ESObject0
{
[JsonProperty("EVTS")]
public ESObject1 EVTS { get; set; }
}
class Program
{
static void Main()
{
string json =
#"{
""EVTS"": {
""EVT"": [
{
""ID"": ""123456"",
""KEY1"": ""somekey"",
""CATEG"": [
""cat1"",
""cat2"",
""cat3""
]
}
]
}
}";
ESObject0 globalobject = JsonConvert.DeserializeObject<ESObject0>(json);
foreach (string item in globalobject.EVTS.EVT[0].CATEG)
{
Console.WriteLine(item);
}
}
}
Maybe you just fed a wrong json value to the deserializer which doesn't look like as the one shown in your question. By the way, the one shown i nyour question is invalid JSON as you are missing a , after KEY1 property declaration.
UPDATE:
Now that you have shown your real JSON (coming from http://donnees.ville.quebec.qc.ca/Handler.ashx?id=69&f=JSON) it appears that there's a row where CATEG is not an array of strings but a simple string:
""CATEG"": ""Conférence""
Now that's a pretty bad design because they are mixing arrays and simple properties. I am afraid that in order to deal with this situation you will need to use JObjects and extract the information you need by testing the actual underlying type.
For example:
var obj = JObject.Parse(json);
var events = (JArray)obj["EVTS"]["EVT"];
foreach (JObject evt in events)
{
var categories = evt["CATEG"];
if (categories is JArray)
{
// you've got a list of strings so you can loop through them
string[] cats = ((JArray)categories)
.Select(x => x.Value<string>())
.ToArray();
}
else
{
// you've got a simple string
string cat = categories.Value<string>();
}
}
I have done this many times with many many headaches. My advice is take the json output and use a tool similar to this to write your class for you (http://json2csharp.com/).
Then go over any nullable variables and add nullable type (ex. using int? for int) where needed.

How to build a Json tree

Here's the json I want to build:
{
id: 0,
item: [{ id: 1, text: "1111"
}, {
id: 2,
text: "222222",
item: [{ id: "21", text: "child" }]
}, {
id: 3, text: "3333"
}]
}
For now I can not build a tree, I can only build something like this:
[{"id":1,"text":"1111"},{"id":21,"text":"child"]
I'm building it with this code:
var serializer = new JavaScriptSerializer();
var jsonString = serializer.Serialize(listOfPairsOfTextAndId);
But how can I build the given tree in c#?
Først issue is that it is somewhat difficult to use an anonymous object to describe your graph i C#. But you can create a class instead:
class Item {
public Int32 id { get; set; }
public String text { get; set; }
public Item[] item { get; set; }
}
Then you can create your object graph:
var graph = new Item {
id = 0,
item = new[] {
new Item {
id = 1,
text = "1111"
},
new Item {
id = 2,
text = "222222",
item = new[] {
new Item {
id = 21,
text = "child"
}
}
},
new Item {
id = 3,
text = "3333"
}
}
};
You are using the Microsoft JSON serializer which will result in this JSON:
{"id":0,"text":null,"item":[{"id":1,"text":"1111","item":null},{"id":2,"text":"222222","item":[{"id":21,"text":"child","item":null}]},{"id":3,"text":"3333","item":null}]}
This is not exactly what you want because of the extra null values. To work around this you can use JSON.NET instead. You have to add some extra attributes to the class being serialized:
class Item {
public Int32 id { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String text { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Item[] item { get; set; }
}
Serialization is then performed using this code:
var jsonString = JsonConvert.SerializeObject(graph);
You get this JSON:
{"id":0,"item":[{"id":1,"text":"1111"},{"id":2,"text":"222222","item":[{"id":21,"text":"child"}]},{"id":3,"text":"3333"}]}
Except for the syntax errors in your question this is what you are asking for.
You need to create some objects that contain the data you want to serialize into that format. I used an online generator to create a couple of quick classes, refactor as necessary for your use.
Here are the classes
public class Item2
{
public string id { get; set; }
public string text { get; set; }
}
public class Item
{
public int id { get; set; }
public string text { get; set; }
public List<Item2> item { get; set; }
}
public class RootObject
{
public int id { get; set; }
public List<Item> item { get; set; }
}
You'll be creating the RootObject first and setting it's properties as necessary (make sure to init the List). After that, simply do the same for the other classes that will make up your output.
After you are done, simple Serialize the RootObject instance and you'll get the output requested.
I used http://json2csharp.com/ to generate those classes based on the desired JSON output.
You can create function like this
public static string GetJSON(object obj)
{
var oSerializer = new JavaScriptSerializer();
var sbJsonResults = new StringBuilder();
oSerializer.Serialize(obj, sbJsonResults);
return sbJsonResults.ToString();
}
And then call this function.
Edit 1
You can create a custom class in which form you want to use.
Create List<class> of that and pass it in the above function
It will work.

How do I deserialize a custom node in Json to c#, whose name keeps changing?

Below is a section of json I receive from an endpoint.
If you look at the Json below, 'User-Defined-Network-Name' is a custom node and the name will change each time.
How do I define a C# object for this Json?
"addresses": {
"public": [{
"version": 6,
"address": "2005:4600:788e:0910:1a72:81c0:ff03:c7y6"
},
{
"version": 4,
"address": "197.68.xx.xxx"
}],
"private": [{
"version": 4,
"address": "10.xx.xx.xxx"
}],
"User-Defined-Network-Name": [{
"version": 4,
"address": "192.xxx.x.xxx"
}]
}
This is how far I have come -
[Serializable]
public class Addresses
{
public List<Public> #public { get; set; }
public List<Private> #private { get; set; }
}
Im using 'JavascriptSerializer' class to deserialize json.
Thanks,
Ryan
addresses can be deserialized to a type like Dictionary<string,List<YourClass>> where YourClass holds version and addresss.
var obj = new JavaScriptSerializer().Deserialize<Root>(jsonstring);
--
public class Root
{
public Dictionary<string,List<VersionAddress>> addresses;
//Your other fields/properties
}
public class VersionAddress
{
public string version;
public string address;
}
You could take advantage of the dynamic nature of C#:
// this could come from user input:
string userDefinedName = "User-Defined-Network-Name";
    string json = "YOUR JSON COMES HERE";
var serializer = new JavaScriptSerializer();
dynamic result = serializer.DeserializeObject(json);
int version = result["addresses"][userDefinedName][0]["version"];
string address = result["addresses"][userDefinedName][0]["address"];
Console.WriteLine(version);
Console.WriteLine(address);
and if you wanted to loop through the results:
foreach (dynamic item in result["addresses"][userDefinedName])
{
int version = item["version"];
string address = item["address"];
Console.WriteLine(version);
Console.WriteLine(address);
}
Why don't you make network names a dictionary, with key of network name ?
Then you can just iterate over it.
I would not recommend using JavaScriptSerializer, as it has been deprecated. If you want a third-party solution, JSON.Net is pretty good from what I hear.
However, I'm one that's weird about dependencies, so I typically roll my own if it doesn't exist already. Fortunately, this one isn't too hard due to DataContractJsonSerializer from the System.Runtime.Serialization namespace.
All you need to do is first define all the objects in a nested fashion:
using System.Reflection;
using System.Runtime.Serialization; // You will have to add a reference
using System.Runtime.Serialization.Json; // to System.Runtime.Serialization.dll
[DataContract]
public class AddressInfo
{
[DataMember(Name = "address")]
public string Address { get; set; }
[DataMember(Name = "version")]
public int Version { get; set; }
}
[DataContract]
public class AddressList
{
[DataMember(Name = "public")]
public IEnumerable<AddressInfo> Public { get; set; }
[DataMember(Name = "private")]
public IEnumerable<AddressInfo> Private { get; set; }
[DataMember(Name = "User-Defined-Network-Name")]
public IEnumerable<AddressInfo> UserDefined { get; set; }
}
Then a couple helper methods to do the deserialization:
// This will change the DataMember.Name at runtime!
// This will only work if you know the node name in advance.
static void SetUserDefinedNodeName(string userDefinedNodeName)
{
var type = typeof(AddressList);
var property = type.GetProperty("UserDefined", BindingFlags.Default);
var attribute = property.GetCustomAttribute<DataMemberAttribute>();
if (attribute != null)
attribute.Name = userDefinedNodeName;
}
static T Deserialize<T>(string jsonText, string userDefinedNodeName)
{
SetUserDefinedNodeName(userDefinedName);
var jsonBytes = Encoding.UTF8.GetBytes(jsonText);
using (var stream = new MemoryStream(jsonBytes))
{
var serializer = new DataContractJsonSerializer(typeof(T));
var obj = serializer.ReadObject(stream) as T;
return obj;
}
}
Then you use it like so:
var jsonText = // get your json text somehow
var addressList = Deserialize<AddressList>(jsonText);

Categories