C# List<string> to JSON objects - c#

I have a list of strings, printing out:
["TEST1","TEST2","TEST3"]
How would I go about transforming this data to this JSON formatting?
[
{
"value": "TEST1"
},
{
"value": "TEST2"
},
{
"value": "TEST3"
}
]
I do not plan on creating an object.
Have tried using dictionary and key value pairs as well.

What about this ?
using System;
using System.Linq;
using System.Text.Json;
public class Program
{
public static void Main()
{
var list = new [] {"TEST1","TEST2","TEST3" };
var str = JsonSerializer.Serialize(list.Select(l => new { Value = l }));
Console.WriteLine(str);
}
}

you can try this
List<string> tests = new List<string> { "TEST1", "TEST2", "TEST3"};
string json = JsonConvert.SerializeObject( tests.Select( t=> new { value = t }));
but I highly recommend to create a class
string json = JsonConvert.SerializeObject( tests.Select( t => new Test { value = t}));
// or if you are using System.Text.Json
string json = JsonSerializer.Serialize(tests.Select( t=>n ew Test { value = t }));
public class Test
{
public string value {get; set;}
}
json
[{"value":"TEST1"},{"value":"TEST2"},{"value":"TEST3"}]

Basically the same as the others, but using a foreach:
public static string[] TestArray = new[] { "TEST1", "TEST2", "TEST3", };
public static string Test()
{
var data = new List<object>(TestArray.Length);
foreach (var item in TestArray)
{
data.Add(new { #value = item });
}
var result = JsonSerializer.Serialize(data);
return result;
}
Gives:
[
{
"value": "TEST1"
},
{
"value": "TEST2"
},
{
"value": "TEST3"
}
]
It uses System.Text.Json, but it should get the same result if you use the Newtonsoft serializer.

Related

How to get the key value json format in an array?

I want to return a particular type of JSON format from my sp.
Below is the JSON format I want:
I am using the dataset to fetch from Query.
I have looped in the data row from the table.
I have used the KeyValuPair type to fetch the data.
But unable to get the desired format, I only get the format key value but how to get that in the metadata.
My desired JSON output
{
"Metadata": [
{
"Key": "FirstName",
"Value": "ABC"
},
{
"Key": "LastName",
"Value": "XYZ"
}
],
"Length": 25,
"Type": "application/mp3"
}
C# code to fetch the data from sp
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
List<Class> objList = new List<Class>();
List<KeyValuePair<string, string>> keyvalList = new List<KeyValuePair<string, string>>();
foreach (DataRow t in ds.Tables[0].Rows)
{
Class obj1 = new Class();
obj1.FirstName = Convert.ToString(t["FirstName "]);
obj1.LastName= Convert.ToString(t["LastName"]);
objList.Add(obj1);
keyvalList.Add(new KeyValuePair<string, string>("FirstName ", Convert.ToString(t["FirstName"])));
keyvalList.Add(new KeyValuePair<string, string>("LastName", Convert.ToString(t["LastName"]);
}
string JSONresult = JsonConvert.SerializeObject(keyvalList);
return JSONresult;
My Class Structure
public class Class
{
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
JSON format which I get
[{\"key":\"FirstName\", \"Value\":\"ABC\"},{\"key":\"LastName\", \"Value\":\"XYZ\"}]
I get the key-value JSON but it does not get inside the metadata array.
Update
var data = new
{
Metadata = dt.AsEnumerable()
.Select(m => new Header
{
key= m.Field<string>("AgentId"),
Value= m.Field<string>("LastName"),
FirstName = m["FirstName"].ToString(),
LastName = m["LastName"].ToString()
}).ToList(),
Length = "25",
Type = "application/mp3"
};
string JSONreult = JsonConvert.SerializeObject(data);
return JSONreult;
Output what I get
{
"Metadata": [
[
{
"Key": "FirstName",
"Value": "ABC"
},
{
"Key": "LastName",
"Value": "DEF"
}
],
[
{
"Key": "FirstName",
"Value": "GEH"
},
{
"Key": "LastName",
"Value": "IJK"
}
]
],
"Length": 25,
"Type": "application/json"
}
Output How I want
{
"Metadata": [
{
"Key": "FirstName",
"Value": "ABC"
},
{
"Key": "LastName",
"Value": "XYZ"
}
],
"Length": 25,
"Type": "audio/mp3",
}
The Difference
The extra [] inside MetaData while I only need one Array.
You have to create a class
public class Data {
public IList<KeyPairValue<string,string>> Metadata{ get; set; }
}
fill it with your values and then serialize that to Json.
You don't need to make many hops like that. You could say use LinqToSQL or LinqToEF, along with Newtonsoft's Json.Net from NuGet and your code would simply be like:
var data = new
{
MetaData = db.TableName
.Select(row => new { Key = row.FieldForKey, Value = row.FieldForValue }),
Length = 25,
Type = "application/mp3"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
If you still want to use ADO.Net instead, you still could do it like:
var tbl = new DataTable();
new SqlDataAdapter(cmd, "your connection string here").Fill(tbl);
var data = new
{
MetaData = tbl.AsEnumerable()
.Select(t => new { Key = t.Field<string>("KeyColumn"), Value = t.Field<string>("ValueColumn")}),
Length = 25,
Type = "application/mp3"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
EDIT: Although I find it weird, here is a full sample using Northwind sample database:
var tbl = new DataTable();
new SqlDataAdapter(#"Select t.*
from Customers c1
cross apply (select 'FirstName', customerId from customers c2 where c1.CustomerId = c2.CustomerId
union
select 'LastName', CompanyName from customers c2 where c1.CustomerId = c2.CustomerId) t([Key], [Value])
",#"server=.\SQLExpress2012;Database=Northwind;Trusted_Connection=yes").Fill(tbl);
var data = new
{
MetaData = tbl.AsEnumerable()
.Select(t => new {
Key = t.Field<string>("Key"),
Value = t.Field<string>("Value") } ),
Length = 25,
Type = "application/mp3"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Answer is updated based on comments
Your question consists of two parts:
1.How to populate DataTable
2.How to serialize it to json (in a custom look)
First of all, Change your class structure like below:
public class Metadata
{
public string FirstName { get; set; }
public string LasstName { get; set; }
}
public class Data
{
public IList<Metadata> Metadata { get; set; }
public int Length { get; set; }
public string Type { get; set; }
}
Then you should populate dt with database query results using Linq:
DataTable dt = new DataTable();
da.Fill(dt);
var listOfData = new Data
{
Metadata = dt.AsEnumerable()
.Select(m => new FullName
{
Key = m["FirstName"].ToString(),
Value = m["LastName"].ToString()
}).ToList(),
Length = 25,
Type = "application/mp3"
};
After serializing listOfData to json using var json = JsonConvert.SerializeObject(listOfData); command, the output would be like this:
{
"Metadata":[
{
"Key":"John",
"Value":"Smith"
},
{
"Key":"Adele",
"Value":"Jones"
}
],
"Length":25,
"Type":"application/mp3"
}
But it differs from your desired output:
{
"Metadata":[
{
"Key":"FirstName",
"Value":"John"
},
{
"Key":"LastName",
"Value":"Smith"
}
],
"Length":25,
"Type":"application/mp3"
}
If you like to change the face of your json and serialize it in custom way, you have to implement a Custon JsonConverter, because JsonSerializer cannot change your model by itself. To do so, you have to create a class and derive it from JsonConverter and override its methods to shape your nodes as you like:
class CustomMetadataConverter<T> : JsonConverter where T : class
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = new JObject(
JArray.Load(reader)
.Children<JObject>()
.Select(jo => new JProperty((string)jo["Key"], jo["Value"]))
);
T result = Activator.CreateInstance<T>();
serializer.Populate(obj.CreateReader(), result);
return result;
}
public override bool CanRead
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JArray array = new JArray(
JObject.FromObject(value)
.Properties()
.Select(jp =>
new JObject(
new JProperty("Key", jp.Name),
new JProperty("Value", jp.Value)
)
)
);
array.WriteTo(writer);
}
}
And then call JsonObject.SerializeObject this way instead of calling it as always:
var json = JsonConvert.SerializeObject(listOfData, Formatting.Indented /* set it depend on your need */, new CustomMetadataConverter<Metadata>());
You can desrialize it in the same way:
var deserializedObject = JsonConvert.DeserializeObject<JObject>(json, new CustomMetadataConverter<Metadata>());
Here is the output:
{
"Metadata": [
[
{
"Key": "FirstName",
"Value": "John"
},
{
"Key": "LastName",
"Value": "Smith"
}
],
[
{
"Key": "FirstName",
"Value": "Adele"
},
{
"Key": "LastName",
"Value": "Jones"
}
]
],
"Length": 25,
"Type": "application/json"
}

How to Deserialize JSON array into dictionary

Stuck on Deserialize issue need help to convert JSON file with data array. I cannot figure out how to deserialize it into a dictionary of this object.
My JSON is in this format in the file - it is thousands of lines long this is just a sample:
[
{
"movies": [
"A",
"B",
"C",
"D",
"E"
]
},
{
"movies": [
"A"
]
},
{
"movies": [
"C",
"D"
]
}
]
So far I understand JSON structure, my C# classes are
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string[] movies { get; set; }
}
var json = "";
// MyObject o;
using (FileStream s = File.Open(#"D:\test.json", FileMode.Open))
using (StreamReader sr = new StreamReader(s))
{
json = sr.ReadToEnd();
}
var tmp = JsonConvert.DeserializeObject<Rootobject>(json);
Can not get DeserializeObject
With only this class
public class Class1
{
public string[] movies { get; set; }
}
Could you try
var tmp = JsonConvert.DeserializeObject<IEnumerable<Class1>>(json);
The problem with the code you posted is that your JSON object is actually an array (note how it starts with [ and ends with ]), but your code is attempting to deserialize it into a singular Rootobject which does not match the structure of your JSON.
You need to deserialize to Class1[] instead, indicating that it is an array.
var tmp = JsonConvert.DeserializeObject<Class1[]>(json);
You are also asking how to get it into a Dictionary type but for that you will need a key value to make a distinction between them. Your incoming format doesn't really make sense for that. You would need something like the following:
test.json
[
{
"key": "keyValue1",
"movies": [
"A",
"B",
"C",
"D",
"E"
]
},
{
"key": "keyValue2",
"movies": [
"A"
]
},
{
"key": "keyValue3",
"movies": [
"C",
"D"
]
}
]
Class Structure
public class Class1
{
public string key { get; set; }
public string[] movies { get; set; }
}
Deserialization
var json = "";
// MyObject o;
using (FileStream s = File.Open(#"D:\test.json", FileMode.Open))
using (StreamReader sr = new StreamReader(s))
{
json = sr.ReadToEnd();
}
var tmp = JsonConvert.DeserializeObject<Rootobject[]>(json);
// don't forget to add using System.Linq;
var dictionary = tmp.ToDictionary<string, string[]>(o => o.key, o => o.movies);

(List<Dictionary<Object, Object>> in Linq to extract data

I have a data definition
I Deserialize JSON to this object
#return is JSON
JsonConvert.DeserializeObject<List<Dictionary<Object, Object>>>(utils.RemoveJsonOuterClass("GetTable", JsonConvert.DeserializeObject(#return).ToString()));
olist = [
[{
"item": 1
"Name "One"
}],
[{
"item": 2
"Name "Two"
}],
[{
"item": 1
"Name "One Two"
}]
];
This is a List<Dictionary<Object, Object>>
I need to find all of the items where "item" == 1.
Can I Use Linq? or is there any other way while using a large amount of data?
First: Your json is not correct fix that.
A colon should be present between Name and value.
A comma should be present after item value
and then change your code as below
//Create a class matching response object
public class ResponseItem
{
[JsonProperty("item")]
public int Item { get; set; }
public string Name { get; set; }
}
var responseJson = utils.RemoveJsonOuterClass("GetTable",
JsonConvert.DeserializeObject(#return).ToString();
var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<List<List<ResponseItem, ResponseItem>>>(responseJson);
Then use foreach with Where and apply condition
foreach (var responseObject in responseData.Where(x=>x.First().Item.Equals(1)))
{
}
Where is deferred execution and on each loop, it returns an object.
Here is the screenshot of my local execution.
Don't know if u're right with the object type. But the task is easy to solve:
static void Main(string[] args)
{
// Build the object
List<Dictionary<int, TestObject>> list = new List<Dictionary<int, TestObject>>();
// fill it with dictionaries
list.Add(new List<TestObject>()
{
new TestObject(){ Id = 1, Name = "One" },
new TestObject() { Id = 2, Name = "Two" },
new TestObject() { Id = 3, Name = "Three" }
}.ToDictionary(d => d.Id));
list.Add(new List<TestObject>()
{
new TestObject() { Id = 2, Name = "Two" },
new TestObject() { Id = 3, Name = "Three" }
}.ToDictionary(d => d.Id));
list.Add(new List<TestObject>()
{
new TestObject(){ Id = 1, Name = "One" },
new TestObject() { Id = 2, Name = "Two" }
}.ToDictionary(d => d.Id));
// Let's build a single list to work with
IEnumerable<TestObject> completeList = list.SelectMany(s => s.Values);
// aaaand filter it
IEnumerable<TestObject> filteredList = completeList.Where(l => l.Id == 1);
}
public class TestObject
{
public int Id { get; set; }
public string Name { get; set; }
}
Most part is initialization ;-)

Deserialise Json file with newtonsoft and query with linq

I'm new to Newtonsoft and I'm trying to deserialise my json file then query specific data points from it. Here is a sample of the json.
[
{
"reward_type": "1",
"rejected": "0",
"user_id": "538653",
"granted": "0"
},
{
"reward_type": "5",
"rejected": "0",
"user_id": "536345",
"granted": "1"
},
{
"reward_type": "5",
"rejected": "0",
"user_id": "539493",
"granted": "1"
}
]
I'm trying to query the values after each type. I've been trying to wrap my head around the documentation for Json.net for a few days, but I'm having trouble finding examples for deserializing files.
Here is what I've been using to parse the file.
InitializeComponent();
JArray adData1 = JArray.Parse(File.ReadAllText(#"c:\ads.json"));
using (StreamReader file = File.OpenText(#"c:\ads.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
JsonSerializer serializer = new JsonSerializer();
JArray adData2 = (JArray)serializer.Deserialize(file, typeof(JArray));
JObject rewardType = (JObject)adData2[1];
label1.Text = rewardType.ToString();
}
Any help is appreciated.
From the suggestions:
Its only useable if the data have a common structure. You can Replace the DataTypes in the POCO, if you like
The POCO
public class Stuff {
public string reward_type { get; set; }
public string rejected { get; set; }
public string user_id { get; set; }
public string granted { get; set; }
}
How to use:
public void doThings() {
// var s = File.ReadAllText("yourfilename.json");
var s = #"{
""reward_type"": ""1"",
""rejected"": ""0"",
""user_id"": ""538653"",
""granted"": ""0""
},
{
""reward_type"": ""5"",
""rejected"": ""0"",
""user_id"": ""536345"",
""granted"": ""1""
},
{
""reward_type"": ""5"",
""rejected"": ""0"",
""user_id"": ""539493"",
""granted"": ""1""
}";
// [] is needed to make it recognize it as list
var listOfStuff = JsonConvert.DeserializeObject<List<Stuff>>("["+s+"]");
foreach (var item in listOfStuff)
{
Console.WriteLine(item.user_id);
}
}

Create collection of objects which has a property of type Collection using Linq

I have the following classes:
public class File
{ public string FileId;
public <Batch> Batches;
public decimal Amount;
}
public class Batch
{ public string FileId;
public string BatchCode;
public decimal Amount;
}
I want to create the following output object:
public class SummaryFile
{
public List<File> Files;
}
Now I have the following list of the Batch class:
List<Batch> batches;
Now this list would look like the following:
batches[0] = new Batch{ FileId = 1, BatchCode = "A", Amount = 5 };
batches[1] = new Batch{ FileId = 1, BatchCode = "B", Amount = 10 };
batches[2] = new Batch{ FileId = 2, BatchCode = "C", Amount = 22 };
My output object is the following:
public class SummaryFile
{
public List<File> Files;
}
I would expect my output to look like the following:
"Files": [
{
"FileId": "1",
"Batches": [
{
"BatchCode": "A",
"Amount": 5
},
{
"BatchCode": "B",
"Amount": 10
},
],
"FileAmount": 15,
},
{
"FileId": "2",
"Batches": [
{
"BatchCode": "C",
"Amount": 22
},
],
"FileAmount": 22
}
]
is it possible to accomplish this using Linq if not what is the best way to accomplish this? Coming from the mainframe I would use control break processing to accomplish this. thanks for any assistance.
var summaryFile = new SummaryFile
{
Files = batches.GroupBy(p => p.FileId)
.Select(p => new File
{
FileId = p.Key,
Batches = p.ToList(),
Amount = p.Sum(x => x.Amount)
}).ToList()
};

Categories