So I have this object:
public class JournalItem
{
public string Description { get; set; }
public bool IsShared { get; set; }
public bool IsDeleted { get; set; }
public bool IsGroup { get; set; }
public Guid Id { get; set; }
public List<JournalItem> ChildEntities { get; set; }
}
It has a list of the same type of object there, ChildEntitites. I've got a page that posts an array of these back to the server as Json. Here's the Json it returns:
[{"Description":"Develop social skills","Id":"d48749ea-2b50-4563-b47c-f2014b08c53a","IsShared":false,"IsDeleted":false,"IsGroup":false,"ChildEntitites":[]},{"Description":"Be more like Joel D.","Id":"a18749ea-2b50-4563-b47c-f2014b08d123","IsShared":true,"IsDeleted":false,"IsGroup":true,"ChildEntitites":[{"Description":"Wear cool glasses","Id":"77c56855-5626-4107-bc82-5862ccdb0943","IsShared":false,"IsDeleted":false,"IsGroup":false,"ChildEntitites":[]},{"Description":"Get 16GB of RAM","Id":"82081eab-b4ce-41fe-bcec-22178b7ed8e6","IsShared":false,"IsDeleted":false,"IsGroup":false,"ChildEntitites":[]}]},{"Description":"Nested group 1","Id":"9495f718-9e7b-4936-b1bf-112d1e7d3ef5","IsShared":false,"IsDeleted":false,"IsGroup":true,"ChildEntitites":[{"Description":"Nested group 2","Id":"70a7e919-1253-4dbd-b41b-49d8bd599657","IsShared":false,"IsDeleted":false,"IsGroup":true,"ChildEntitites":[{"Description":"Nested group 3","Id":"77bfcb11-cba2-48a9-8a1b-b4e0c9b1c5e1","IsShared":false,"IsDeleted":false,"IsGroup":true,"ChildEntitites":[{"Description":"Very nested objective","Id":"274c786b-d09c-4228-a18a-629d4ca9aed3","IsShared":false,"IsDeleted":true,"IsGroup":false,"ChildEntitites":[]}]}]}]}]
Here's how I'm using JavaScriptSerilaiazer to conver it to an actual object:
var ser = new JavaScriptSerializer();
var journalStructure = ser.Deserialize<List<JournalItem>>(journalJson);
(I've also tried NewtonSoft with the same result)
This should give me an array of 3 items (which it does). The first item shouldn't have any ChildEntities, but the second and third should have another list of JournalItems as their ChildEntities, but those are also both null.
How can I get one of these serializer things to deserialize the json array as a list? Can I do that?
It should work if you change ChildEntities to ChildEntitites (your json string contains this)
Both Json.net and JavaScriptSerializer work.
Related
I got this strange API response from one external service:
{emplooye: "Michael",age:"25",attachments:[{idAttachment: "23",attachmentPath:"C://Users/1"},{idAttachment: "24",attachmentPath:"C://Users/2"}]},{emplooye: "John",age:"30",attachments:{idAttachment: "25",attachmentPath:"C://Users/3"}}
Has anyone ever faced a situation where sometimes the "Attachment" property can be an array, sometimes it can be an object? I created a class to manipulate the data, but when I find an object, the code breaks.
I'm doing this in C#.
Class Used
public class Attachments
{
public string idAttachment{ get; set; }
public string attachmentPath{ get; set; }
}
public class Root
{
public string emplooye {get; set;}
public string age {get;set}
public List<Attachments> attachments { get; set; } = new List<Attachments>();
}
your json is not even close to json, should be something like this
var json = "[{\"emplooye\":\"Michael\",\"age\":\"25\",\"attachments\":[{\"idAttachment\":\"23\",\"attachmentPath\":\"C://Users/1\"},{\"idAttachment\":\"24\",\"attachmentPath\":\"C://Users/2\"}]},{\"emplooye\":\"John\",\"age\":\"30\",\"attachments\":{\"idAttachment\":\"25\",\"attachmentPath\":\"C://Users/3\"}}]";
Using Newtonsoft.Json you can create a JsonConstructor
using Newtonsoft.Json;
List<Data> data= JsonConvert.DeserializeObject<List<Data>>(json);
public class Data
{
public string emplooye { get; set; }
public string age { get; set; }
public List<Attachments> attachments { get; set; }
[JsonConstructor]
public Data(JToken attachments)
{
if (attachments.Type.ToString() == "Array")
this.attachments = attachments.ToObject<List<Attachments>>();
else
this.attachments = new List<Attachments> { attachments.ToObject<Attachments>() };
}
public Data() {}
}
public class Attachments
{
public string idAttachment { get; set; }
public string attachmentPath { get; set; }
}
You can use Newtonsoft to parse to a JToken which will handle the typing for you, but with the downside of not having a stable and predictable class to deserialize to automatically
Then, you would want to check its type, which returns a JTokenType enum
Once you know what the underlying types are, marshal the data into your DTO classes
JToken responseJT = JToken.Parse(json); //json string
if (responseJT.Type == JTokenType.Array)
//its an array, handle as needed ...
else if (responseJT.Type == JTokenType.Object)
//its an object, handle as needed ...
Personally, I would keep the attachments property as a List<Attachments> and if the JToken has a JSON object I would just set it as the [0] index of that property. This way things stay consistent and you can use LINQ on that property with ease
I have a string in JSON format as follows
string jsonStr = "{"Type":1, "Id":1000,"Date":null,"Group": "Admin","Country":"India","Type":1}";
I want to modify this string so that Id attribute should always be the first. The order of attributes matters.
Is there any way I can modify this string.
I tried searching google but did not find appropriate solution.
Any help would be appreciated.
EDIT:
I also tried to deserialize object using
object yourOjbect = new JavaScriptSerializer().DeserializeObject(jsonStr);
But here also the "type" attribute comes first. I dont find any way to move the attributes within this deserialized object
It's possible. Use the JsonProperty attribute, property Order.
http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm.
Let me know if it works.
Instead of attempting to manipulate the order of the outputted JSON and comparing strings, I would transform both JSON strings that you want to compare, into objects and then perform your comparison. You could then compare individual properties or entire objects with something like the following:
void CompareJSON()
{
string json = #"{""Type"":1, ""Id"":1000,""Date"":null,""Group"": ""Admin"",""Country"":""India"",""Type"":1}";
string jsonToCompare = "JSON TO COMPARE";
MyObject myJsonObject = JsonConvert.DeserializeObject<MyObject>(json);
MyObject myJsonObjectToCompare = JsonConvert.DeserializeObject<MyObject>(jsonToCompare);
if (myJsonObject.Id == myJsonObjectToCompare.Id)
{
// Do something
}
}
class MyObject
{
public int Id { get; set; }
public int Type { get; set; }
public DateTime? Date { get; set; }
public string Group { get; set; }
public string Country { get; set; }
}
Please note that this example is carried out using the Newtonsoft.JSON library. More information on the library can be found here.
Just make your JSON into a c# class with Id first and then serialize it again if that is what you need. You do know that you have "Type" twice in the JSON string? In this solution it will get "fixed" so you only have it once as it should be. But if your string really is with two Type this wont work since the strings will be incorrect. If they really are like that you need to do some ugly string manipulation to fix the order but i hope the first string is incorrect only here and not in your code.
private void Test() {
string json = #"{""Type"":1, ""Id"":1000,""Date"":null,""Group"": ""Admin"",""Country"":""India"",""Type"":1}";
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
MyJsonObject myJsonObject = jsonSerializer.Deserialize<MyJsonObject>(json);
string s = jsonSerializer.Serialize(myJsonObject);
//Returns: {"Id":1000,"Type":1,"Date":null,"Group":"Admin","Country":"India"}
}
class MyJsonObject {
public int Id { get; set; }
public int Type { get; set; }
public DateTime? Date { get; set; }
public string Group { get; set; }
public string Country { get; set; }
}
I have seen some other questions like this, but those are quite complex JSON data's that have objects within objects. Although the JSON I'm working with is never static, I doubt it's as complex as those. Also, it's my first time using JSON with C# so I'm a little clueless.
What I'm trying to achieve is to separate the data that is received from an API that I prompt using WebRequest in C#.
{
"johhny.debt": {
"id":35187540,
"name":"johnny.debt",
"profileIconId":786,
"Level":30,
"revisionDate":1428019045000
}
}
The returned JSON data is in a fashion like thereof.
I want to be able to access all of the properties of the above string in the following manner:
ID :
Name:
~~
~~
~~
... and so forth.
I'm assuming some type of class has to be made for this?
All help is appreciated, thank you all in advance.
Install Json.Net from Nuget
Install-Package Newtonsoft.Json
https://www.nuget.org/packages/Newtonsoft.Json/
Declare class for inner object ({"id":..., "name": ... }):
public class InnerObject
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Username { get; set; }
[JsonProperty("profileIconId")]
public int ProfileIconId { get; set; }
[JsonProperty("level")]
public int Level { get; set; }
[JsonProperty("revisionDate")]
public string RevisionDate { get; set; }
}
As you can see you can specify rename mapping from json fields to .Net object properties using JsonPropertyAttribute.
Read your json to Dictionary<string,InnerObject> and get value of "johhny.debt" key:
var dict = JsonConvert.DeserializeObject<Dictionary<string, InnerObject>>(jsonText);
var johhny = dict["johhny.debt"];
Or if your need always to parse exact json property 'johhny.debt', you could create root object class:
public class RootObject
{
[JsonProperty("johhny.debt")]
public InnerObject JohhnyDept { get; set; }
}
And deserialize it:
var root = JsonConvert.DeserializeObject<RootObject>(jsonText);
var johhny = root.JohhnyDebt;
Just Create a class like this
public class RootObject
{
public int Id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int Level { get; set; }
public string revisionDate { get; set; }
}
then install json.Net and this code to your main method
var jsonObject=JsonConvert.DeserializeObject<RootObject>(jsonText);
That's all
Update
var obj = JObject.Parse(json);
var RootObject = new RootObject()
{
Id = (int)obj["johhny.debt"]["id"],
Level = (int)obj["johhny.debt"]["Level"],
name = (string)obj["johhny.debt"]["name"],
profileIconId = (int)obj["johhny.debt"]["profileIconId"],
revisionDate = (string)obj["johhny.debt"]["revisionDate"]
};
I'm using c# driver to interact with mongoDB.
I have a class that I created and which I populate with the data I get from mongoDB.
One of the properties in that class is DateTime.
The value I get from mongo is /\Date(number)/. Which is ok because this is what I'm suppose to return to the client.
The value that I get from mongo after I retrieve the data is ISODate(some number).
I get an exception: "Invalid JSON primitive: ISODate".
How can I configure mongoDB to save the DateTime like I got it i.e. /\Date(number)/?
Sorry L.B - I didn't noticed your answer but went straight to the answer I was given.
Here's the class I'm trying to deserialize:
public class EventDate
{
public EventDate()
{
}
public int? VenueConfigID { get; set; }
public string Category { get; set; }
public DateTime DateAndTime { get; set; }
public string DisplayDate { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public string ShortNote { get; set; }
public string Home { get; set; }
public int? ID { get; set; }
public string Name { get; set; }
}
Here's how I deserialize it:
mongo = MongoServer.Create();
mongo.Connect();
db = mongo.GetDatabase("productionDB");
var col = db.GetCollection<BsonDocument>("eventDates");
var query = Query<PerformerDates>.EQ(ev => ev.PerformerID, performerId);
//MongoCursor<BsonDocument> performer = col.Find(query);
MongoCursor<BsonDocument> performer = col.FindAll();
JavaScriptSerializer js = new JavaScriptSerializer();
List<EventDate> finalMatchedDates = new List<EventDate>();
foreach (var p in performer)
{
//System.Threading.Tasks.Task<EventDate[]> obj2 = JsonConvert.DeserializeObjectAsync<EventDate[]>(p.Elements.ToList()[3].Value.ToString());
EventDate[] obj3 = JsonConvert.DeserializeObject<EventDate[]>(p.Elements.ToList()[3].Value.ToString());
}
mongo.Disconnect();
Solved!!
Eventually I solved it. I used a string instead of a DateTime. When I get it from the DB, I convert it to a DateTime and when I sent it back to the client I serialize it with the format of: /\Date()/
Just use BsonSerializer.Deserialize method.
MongoDB's serializer has a much higher performance over NewtonSoft's Json.Net or Microsoft's DataContractSerializer.
Very common occurring problem! One solution is to use JSON.NET.
See this answer for more help. Although you might be confused with JSON DateTime object but don't worry. It will work!
string json; // Assign JSON here.
var v = Newtonsoft.Json.JsonConvert.DeserializeObjectAsync<T>(json);
I need to deserialize a json array:
{"response":
[19,
{"mid":1068,
"date":1343848664,
"out":1,
"uid":44852633,
"read_state":1,
"title":" ... ",
"body":"А я вовсю."},
{"mid":1007,
"date":1328782448,
"out":1,
"uid":16098752,
"read_state":0,
"title":" ... ",
"body":"http:\/\/theantidj.net\/wp-content\/themes\/theantidjnet\/images\/khubvio.php"}
and so on. I'm using json.net. Can I perform deserealization using JsonConvert.DeserializeObject()? And if so what classes should I create?
Just another solution.
var itemList = ((JObject)JsonConvert.DeserializeObject(json))["response"]
.Skip(1)
.Select(x => JsonConvert.DeserializeObject<Item>(x.ToString()))
.ToList();
public class Item
{
public int mid { set; get; }
public string date { set; get; }
public int #out { set; get; }
public int uid { set; get; }
public int read_state { set; get; }
public string title { set; get; }
public string body { set; get; }
}
L.B. provided the solution. But i would notice if my memory serves me well that JObject is used for dynamic types. Thus it requires .Net 4 or higher. Just in case.
You can use JsonConvert.DeserializeObject<RootObject>(jsonstring) after you define this RootObject.
The tool I use is http://json2csharp.com where you simply put in JSON and get out a corresponding object. You will want to make sure your JSON is well formed though, since in its current form it is not parsing.