How to deserialize JSON date time from MongoDB to C# class - c#

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);

Related

How can parse dynamic json in c#?

Have some json and parse that whit this code:
dynamic json = JsonConvert.DeserializeObject(response.Content);
dynamic result =json.result;
after this line:
dynamic result =json.result;
have this output:
{
{
"321":{
"online_status":true,
"basic_info":{
"status":"Recharged",
"group_name":"IRN-UV002-M01",
"isp_name":"Main",
"creation_date":"2017-09-05 08:19:32",
"recharge_deposit":0.0,
"user_id":321,
"nearest_exp_date":"2018-02-22 10:21:00",
"credit":20387.775145462037,
"deposit":0.0,
"isp_id":0,
"group_id":72
},
"user_repr":"10001168-2100104f4Y8-FTTH",
}
}
}
and now want to get user_id from that json,how can i write code for that purpose?thanks.
The better way would be to deseralize this into a strongly typed object.
But for you you can use the JObject class to do something like the following (note not tested, but you should understand the concept):
dynamic result = JObject.Parse(source);
int id = result.321.basic_info.user_id;
You probably want to do something like this:
var yourInstance = JsonConvert.DeserializeObject<YourClass>(responseJson);
For that, you need to define a class YourClass and related sub-classes which have properties matching the values returned in the JSON data, i.e. something like:
public class YourClass {
public bool online_status { get; set; }
public BasicInfo basic_info { get; set; }
public string user_repr { get; set; }
}
public class BasicInfo {
public string status { get; set; }
public string group_name{ get; set; }
public string isp_name{ get; set; }
public DateTime creation_date{ get; set; }
public string group_name{ get; set; }
// ...etc.
}
With this in place, JsonConvert should be able to understand and parse your data to the correct object.
This is just a rough example, but it should get you on your way.
Another way is to use JObject to hold the string.
var str = "{\"321\":{\"online_status\":true,\"basic_info\":{\"status\":\"Recharged\",\"group_name\":\"IRN-UV002-M01\",\"isp_name\":\"Main\",\"creation_date\":\"2017-09-05 08:19:32\",\"recharge_deposit\":0.0,\"user_id\":321,\"nearest_exp_date\":\"2018-02-22 10:21:00\",\"credit\":20387.775145462037,\"deposit\":0.0,\"isp_id\":0,\"group_id\":72},\"user_repr\":\"10001168-2100104f4Y8-FTTH\"}}";
var obj = JObject.Parse(str);
var userId = obj["321"]["basic_info"]["user_id"].ToString();

Unable to use JSON data with Newtonsoft.Json in WPF

I am retrieving data from office365 api. The response is in JSON format. I want to get data like Id, DisplayName etc. into variables but not getting the right way to do it. Following this link. I'm new to API and JSON. Will Appreciate pointers as well towards best learning links.Sample JSON below for listing sub folders of Inbox folder.
Response JSON data.
{"#odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me/Folders('Inbox')/ChildFolders","value":
[
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmsdfsdfdDSFSDFDFDF=')",
"Id":"AAMkADBjMdfgdfgDFGDFGDFGdfGDFGDFGDFGGDzrACAAB4xqMmAAA=",
"DisplayName":"SampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":8,"TotalItemCount":94},
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEasdasdasdASDASDASDASDSADDASDASDAB4xqMnAAA=')",
"Id":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmOGZkNGRhZmIzNQAuAasdASDASDASDASEDASDASDxSEHjzrACAAB4xqMnAAA=",
"DisplayName":"AnotherSampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":21,"TotalItemCount":75}
]
}
The C# code using to parse JSON and find the required data.
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
throw new WebException(response.StatusCode.ToString() + ": " + response.ReasonPhrase);
string content = response.Content.ReadAsStringAsync().Result;
JObject jResult = JObject.Parse(content);
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
var folderName = results.Id;
var folderId = results.Name;
//Attempt two - [Not working - Throwing exception -
//Object reference not set to an instance of an object.]
var folderID = (string)jResult["odata.context"]["odata.id"][0]["Id"];
First create a class for your json object
public class RootObject
{
[JsonProperty(PropertyName = "#odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty(PropertyName = "#odata.id")]
public string dataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Then Json Convert the Json string to your RootObject if your are using Newtonsoft Json then Deserilaze by using
RootObject shortiee = JsonConvert.DeserializeObject<RootObject>("Your Json String");
private List<string> GetDisplayNames(JObject content)
{
var obj = Json.Parse(content);
var values = obj["value"].ToList();
var displayNames = new List<string>();
foreach (var value in values)
{
displayNames .Add(system["DisplayName"].ToString());
}
return displayNames;
}
This would return the names, for example, and you could do this for each value you need to retrieve. However, this does not require you to serialize/deserialize the json object before using it. It works, but is most likely not best practice.
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
Side note: There is no key called "odata.error" in your JSON data. So you're effectively calling something which will return null.
One of the ways to deserialise JSON is to create model classes for the objects you want to process and deserialise into them directly, eg. JsonConvert.DeserializeObject<Folder>(content). As you are talking to an Office365 API, you find documentation and examples here on how they are defined.
Taken your folder response as an example, your model for a single Folder could look like this:
public class Folder
{
[JsonProperty(PropertyName = "#odata.id")]
public string OdataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Note1: in your example, you get a response with list of folders, so have to adjust this accordingly.
Note2: you can use JsonProperty to define a mapping between a JSON property/key and a C# property as shwon for #odata.id.
However, you can also use the Outlook Client Library which would make it mostly unnecessary to deal with JSON data directly (which seems preferable, unless you have a very specific reason to deal with JSON directly).

Modify a JSON string

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; }
}

How to insert ISODate(DateTime) to mongodb with c#

I have one class.
I adding class to mongodb.
but DateTime Properties as shows the string
c#
public class FRM_FORMREQUEST
{
public int ORACLE_ID { get; set; }
public string FORMNUMBER { get; set; }
public string COMPANYCODE { get; set; }
public DateTime? RECORDDATE { get; set; }
public string RECORDUSER { get; set; }
}
mongodb record
{
"_id" : ObjectId("56927dfc249d951f1031f526"),
"ORACLE_ID" : 771653,
"FORMNUMBER" : "4992014309217",
"COMPANYCODE" : "499",
"RECORDDATE" : "2014-08-21T19:35:27",
"RECORDUSER" : "parttime35"
}
Business
var jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(FRM_FORMREQUEST);
MongoDB.Bson.BsonDocument document = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(jsonData);
frmFormCollection.Insert(document);
I want insert like Date
thanks for all help.
The problem is that you're serializing it to JSON using Json.Net, which will write the dates as strings in the ISO 8601 standard format by default. Then you're de-serializing it to a BsonDocument using the BsonSerializer, which (unless you give it any other instructions) will just assume those are strings.
I have to ask, why jump through these hoops? Why not just let the driver serialize your object for you when you call Insert()?
collection.Insert(FRM_FORMREQUEST);
Or, if you have to work with a BsonDocument, use the mongo BsonSerializer to convert your object directly (instead of converting it to Json first).
var document = FRM_FORMREQUEST.ToBson();
collection.Insert(document);

How Can I Deserialize JSON Data Using C#?

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"]
};

Categories

Resources