I'm trying to build a json (with success) but now i need to deserialize the json, it's the first time i'm using json so i don't really know what do to. I got that's exception when i try to deserialize:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,Boosty.AltsInfos[]]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.
Serializer:
var json = new List<Alts>();
List<AltsInfos> p1 = new List<AltsInfos> { new AltsInfos { alts_name = "JeSaisPas", alts_email = "truc2fou#g.com", alts_pass = "azerty", alts_type = AltsInfos.AltType.Microsoft } };
json.Add(new Alts { account = p1 });
List<AltsInfos> p2 = new List<AltsInfos> { new AltsInfos { alts_name = "TrucBidule", alts_email = "trucmachun#g.com", alts_pass = "azerty2.0", alts_type = AltsInfos.AltType.Microsoft } };
json.Add(new Alts { account = p2 });
string jsonString = JsonConvert.SerializeObject(json, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented });
File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + #"/BoostyLauncher" + #"/alts.json", jsonString);
Deserializer
using (StreamReader sr = new StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + #"/BoostyLauncher" + #"/alts.json"))
{
string json = sr.ReadToEnd();
List<AltsInfos> alts = JsonConvert.DeserializeObject<List<AltsInfos>>(json);
foreach (var item in alts)
Console.WriteLine(item.alts_email);
}
Type containers
class Alts
{
public List<AltsInfos> account { get; set; }
}
class AltsInfos
{
public string alts_name { get; set; }
public string alts_email { get; set; }
public string alts_pass { get; set; }
public AltType alts_type { get; set; }
public enum AltType
{
[EnumMember(Value = "Microsoft")]
Microsoft,
[EnumMember(Value = "Altening")]
Altening
}
}
All i want is to extract alts_name for each account category. Also i don't know how i set the enum in the json it's set to 0.
[
{
"account": [
{
"alts_name": "JeSaisPas",
"alts_email": "truc2fou#g.com",
"alts_pass": "azerty",
"alts_type": 0
}
]
},
{
"account": [
{
"alts_name": "TrucBidule",
"alts_email": "trucmachun#g.com",
"alts_pass": "azerty2.0",
"alts_type": 0
}
]
}
]
You need to fix a bug in your deserialize code. Instead of List< AltsInfos > use List< Alts >
List<Alts> alts = JsonConvert.DeserializeObject<List<Alts>>(jsonString);
foreach (var alt in alts)
foreach (var item in alt.account)
Console.WriteLine(item.alts_email);
or you can use LINQ
List<string> emails = alts.SelectMany(a => a.account.Select(s => s.alts_email)).ToList();
and BTW if you want a json string to be indented, fix the serializer options too
string jsonString = JsonConvert.SerializeObject(json, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore});
I have made changes in deserialized line.
should always deserialze into same class (which serialized into json) that is List< Alts >.
var json = new List<Alts>();
List<AltsInfos> p1 = new List<AltsInfos> { new AltsInfos { alts_name = "JeSaisPas", alts_email = "truc2fou#g.com", alts_pass = "azerty", alts_type = AltType.Microsoft } };
json.Add(new Alts { account = p1 });
List<AltsInfos> p2 = new List<AltsInfos> { new AltsInfos { alts_name = "TrucBidule", alts_email = "trucmachun#g.com", alts_pass = "azerty2.0", alts_type = AltType.Microsoft } };
json.Add(new Alts { account = p2 });
string jsonString = JsonConvert.SerializeObject(json, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented });
**List<Alts>** alts = JsonConvert.DeserializeObject<**List<Alts>**>(jsonString);
Please let me know if it solve your problem otherwise will try to explain more.
Related
var AdditionalData = flexEventTriggerLogsList.Select(x => x.AdditionalData).ToString();
string json = Convert.ToString(JsonConvert.DeserializeObject(AdditionalData));
var objTriggerLog = new FlexEventTriggerLog();
objTriggerLog.lookupEntity_RecordId = ????
objTriggerLog.DocumentRecordIds = ????
Additinal data wil return my Json object in string. I have to use that object to get my entity and document record ids.
Json object which will be returned:
{
"lookupEntity_RecordId": "00000000-0000-0000-0000-000000000000",
"DocumentRecordIds":["00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"]
}
You can use JsonConvert.DeserializeObject(jsonstring)
You create a model for your json
public class AdditionalDataModel
{
public string lookupEntity_RecordId { get; set; }
public List<string> DocumentRecordIds { get; set; }
}
then deserialize your json in model
var AdditionalData = flexEventTriggerLogsList.Select(x => x.AdditionalData).ToString();
var additionalDataModel = JsonConvert.DeserializeObject<AdditionalDataModel>(AdditionalData);
var objTriggerLog = new FlexEventTriggerLog();`
objTriggerLog.lookupEntity_RecordId = additionalDataModel.lookupEntity_RecordId;
objTriggerLog.DocumentRecordIds = additionalDataModel.DocumentRecordIds;
I am trying to get values from a JSON object and save them into 2 lists. I am struggling with understanding how to loop through the JSON object to get the JSON array values.
I believe I am Deserializing correctly, but I am stuck going forward. Here is what I currently have
JObject jsonResult = {"foodtype": ["Pizza", "Pasta", "Bread"],
"drinks": ["Coke", "Root Beer"]}
public class Rootobject
{
public string[] foodType { get; set; }
public string[] drinks { get; set; }
}
var allObject = JsonConvert.DeserializeObject<Rootobject>(jsonResult.ToString());
What I am wanting is for 2 lists to be generated from the JSON result like so:
List<string> food = new List<string> {Pizza, Pasta, Bread}
List<string> drink = new List<string> {Coke, Root Beer}
Your code is invalid, the snippet below is incorrect:
JObject jsonResult = {"foodtype": ["Pizza", "Pasta", "Bread"],
"drinks": ["Coke", "Root Beer"]}
You need to have a string which can be deserialized.
The code below should help you:
static void Main(string[] args)
{
var objectToSerialize = new Rootobject()
{
Drinks = new [] {"Coke", "Root Beer" },
FoodType = new[] { "Pizza", "Pasta", "Bread" }
};
var serializedByTheLib = JsonConvert.SerializeObject(objectToSerialize);
string jsonResult =
"{ \"foodtype\": [\"Pizza\", \"Pasta\", \"Bread\"], \"drinks\": [\"Coke\", \"Root Beer\"] }";
var deserializedObject = JsonConvert.DeserializeObject<Rootobject>(jsonResult);
}
public class Rootobject
{
[JsonProperty("foodType")]
public string[] FoodType { get; set; }
[JsonProperty("drinks")]
public string[] Drinks { get; set; }
}
Key concepts:
An object can be serialized to JSON
A JSON string can be deserialized to an Object
Take a look at newtonsoft documentation to get more info
When you have deserialized the json string to your Rootobject, you can just pick the properties of it:
string json = "{\"foodtype\": [\"Pizza\", \"Pasta\", \"Bread\"], \"drinks\": [\"Coke\", \"Root Beer\"]}";
Rootobject rootObject = JsonConvert.DeserializeObject<Rootobject>(json);
List<string> food = rootObject.foodType.ToList();
List<string> drinks = rootObject.drinks.ToList();
My Web API (code that generates JSON) is generating the following JSON string. It seems, if I am not wrong, that it has been encoded twice:
"\"[{\\\"SportID\\\":1,\\\"SportName\\\":\"Tennis\\\"},{\"SportID\\\":2,\\\"SportName\\\":\\\"Footbal\\\"},{\"SportID\\\":3,\"SportName\":\\\"Swimming\\\"}]\""
Web API code:
public string JSONTest()
{
List<Sport> sports = new List<Sport>();
sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
try
{
return JsonConvert.SerializeObject(sports);
}
catch (Exception ex) { }
}
Sport class:
public class Sport { public int SportID { get; set; } public string SportName { get; set; } }
Screenshot of getting JSON:
The following line gives me an error, I think because of twice encoding:
var JavaScriptSerializerResult = (new JavaScriptSerializer()).Deserialize< List<Sport>>(jsonResponse);
I get the same error if try with this:
var jsonConvertResult = JsonConvert.DeserializeObject<List<Sport>>(jsonResponse);
How can I fix my Web API to not encode twice, or if that is not the problem, how can I decode this JSON?
I think you should try JsonConvert.DeserializeObject to deserialize the JSON:
public class Sport
{
// Dummy "Sport" class as it was not mentioned by OP.
public int SportID { get; set; }
public string SportName { get; set; }
}
I get serialized JSON as:
Deserialized it:
string json = JSONTest();
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
Output:
UPDATE:
As per OP's shared JSON (which is being received from server), encoding can be removed by using:
private string RemoveEncoding(string encodedJson)
{
var sb = new StringBuilder(encodedJson);
sb.Replace("\\", string.Empty);
sb.Replace("\"[", "[");
sb.Replace("]\"", "]");
return sb.ToString();
}
Deserialize it by:
string js = "\"[{\\\"SportID\\\":1,\\\"SportName\\\":\"Tennis\\\"},{\"SportID\\\":2,\\\"SportName\\\":\\\"Footbal\\\"},{\"SportID\\\":3,\"SportName\":\\\"Swimming\\\"}]\"";
string res = RemoveEncoding(js);
var obj = JsonConvert.DeserializeObject<List<Sport>>(res);
Shorter sample for json.net library.
Here, entity is my serializable C# object. I use JsonConvert along with some formatting and specify to ignore reference looping to prevent circular referencing.
using Newtonsoft.Json;
var json = JsonConvert.SerializeObject (entity, Formatting.Indented,
new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
});
Use Linq Query Concept:
public string JSONTest()
{ List<Sport> sports = new List<Sport>();
sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
var result_sports = (from row in sports
group row by new { row.SportID , row.SportName} into hdr
select new Sport()
{
SportID = hdr.Key.SportID ,
SportName = hdr.Key.SportName ,
}).ToList();
string jsondata = new JavaScriptSerializer().Serialize(result_sports);
}
Summary: Your return object is being serialized twice. Remove your hand-rolled serialization code and return objects from your web services - not JSON strings.
Your JSON is indeed being serialized 'twice'. Look closely at this screenshot and we see escaped quote marks:
Your list properly serialized should produce a JSON string something like this:
[{"SportID":1,"SportName":"Tennis"},{"SportID":2,"SportName":"Footbal"},{"SportID":3,"SportName":"Swimming"}]
But we have something more like this:
"[{\"SportID\":1,\"SportName\":\"Tennis\"},{\"SportID\":2,\"SportName\":\"Footbal\"},{\"SportID\":3,\"SportName\":\"Swimming\"}]"
I can replicate this (code below) and it means that your JSON string has itself been fed through a serializer.
This is almost certainly due to you manually serializing your List<Sport>. You don't need to do that. Web API serializes for you - hence the second run through a serializer.
Change the return type of your Web API function if necessary, and then instead of writing:
return JsonConvert.SerializeObject(sports);
just do
return sports;
Web API will take care of the serialization and you will no longer have the bothersome quotes and escape characters.
Code dump I tested with:
void Main()
{
string json = JSONTest();
Console.WriteLine(json);
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
string jsonX2 = JsonConvert.SerializeObject(json);
Console.WriteLine(jsonX2);
obj = JsonConvert.DeserializeObject<List<Sport>>(jsonX2); // exception
}
public string JSONTest()
{
List<Sport> sports = new List<Sport>();
sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
return JsonConvert.SerializeObject(sports);
}
public class Sport
{
public int SportID { get; set; }
public string SportName { get; set; }
}
I'm using the Newtonsoft Json Converter to serialize and deserialize objects and it works great for my program.
But if any of the values stored within the object are null/empty, they are serialized as {}, unable to be deserialized, and my program stops.
For example, if I deserialize the following code, everything works great:
{
"Thing1": 2,
"Thing2": false,
"Thing3": "string",
"Thing4": "2017-10-28T14:04:24.74"
}
But if I try to deserialize the following code:
{
"Thing1": {},
"Thing2": false,
"Thing3": "",
"Thing4": {}
}
Thing1 and Thing4 will both cause problems during deserialization.
Not sure if this could be related to the way I am reading from my database to serialize:
var r = Serialize(myReader);
string json = JsonConvert.SerializeObject(r,
Formatting.Indented,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
public IEnumerable<Dictionary<string, object>> Serialize(SqlDataReader reader)
{
var results = new List<Dictionary<string, object>>();
var cols = new List<string>();
for (var i = 0; i < reader.FieldCount; i++)
cols.Add(reader.GetName(i));
while (reader.Read())
results.Add(SerializeRow(cols, reader));
return results;
}
private Dictionary<string, object> SerializeRow(IEnumerable<string> cols,
SqlDataReader reader)
{
var result = new Dictionary<string, object>();
foreach (var col in cols)
result.Add(col, reader[col]);
return result;
}
I've used:
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }
Within my deserializer:
BlankObject blnkObj = JsonConvert.DeserializeObject<BlankObject>(json, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
How can I deserialize an empty value? Thanks in advance.
You need to have a class structure like following:
public class RootObject
{
public object Thing1 { get; set; }
public bool Thing2 { get; set; }
public string Thing3 { get; set; }
public object Thing4 { get; set; }
}
Figured out my problem thanks to the comment by #dbc
An object of null value is serialized as {} in JSON instead of null
The deserializer did not like deserializing {} into an int. Because a null object is of a different type than an int or DateTime.
My solution was to serialize the results of the database to have null instead of {} by reading from the database like this:
BlankClass test = new BlankClass();
string json = "";
if (myReader.Read())
{
test.Thing1 = (int)myReader[0];
test.Thing2 = (bool)myReader[1];
test.Thing3 = (string)myReader[2];
test.Thing4 = (Datetime?)myReader[3];
json = JsonConvert.SerializeObject(test, Formatting.Indented);
}
class BlankClass
{
int Thing1 { get; set; }
bool Thing2 { get; set; }
string Thing3 { get; set; }
DateTime? Thing4 { get; set; }
}
I have a list of a custom object with two properties that needs to be serialized into JSON. Here is the object:
public class IndexData
{
public string ColumnName { get; set; }
public string Data { get; set; }
}
I need the JSON for the List to be returned like this:
{ "IndexData" : [
{ "Column1": "Data1",
"Column2": "Data2"
}
]
}
Is this possible?
List<IndexData> list = new List<IndexData>()
{
new IndexData(){ColumnName="column1",Data="data1"},
new IndexData(){ColumnName="column2",Data="data2"},
};
//Using Json.Net
var json1 = JsonConvert.SerializeObject(
new {IndexData=list.ToDictionary(x => x.ColumnName, x => x.Data)});
//Using JavaScriptSerializer
var json2 = new JavaScriptSerializer().Serialize(
new { IndexData = list.ToDictionary(x => x.ColumnName, x => x.Data) });
Use JavaScriptSerializer
var indexdata = new IndexData();
var json = new JavaScriptSerializer().Serialize(indexdata);
OR DataContractJsonSerializer
MemoryStream s = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(IndexData));
s.Position = 0;
StreamReader sr = new StreamReader(s);
var json = sr.ReadToEnd();
I'm a big fan of Json.Net
You can use the SerializeObject call to simple serialize your object:
var list = new List<IndexData> {new IndexData {ColumnName = "Foo", Data = "Bar"}};
var output = JsonConvert.SerializeObject(list);
output will then be set to
[{"ColumnName":"Foo","Data":"Bar"}]