C# mongodb driver query nested array - c#

I am struggling now since hours to get one query working. My shema looks like the following:
public class ActionResponse
{
public string Id { get; set; }
public List<ActionResponseItem> ResponseItems { get; set; }
}
public class ActionResponseItem
{
public string Id { get; set; }
public DateTime Created { get; set; }
public List<string> Options { get; set; }
}
Let's assume I've following collection:
[
{
"_id": ObjectId("62bd901c4af4e9d2e1287984"),
"ResponseItems": [
{
"_id": ObjectId("62bd9068b4598dd0bb07b536"),
"Created": ISODate("2022-05-30T08:45:31.662Z"),
"Options": [
"Some string 1",
"Some string 2"
]
},
{
"_id": ObjectId("62bd906e35087e146b6b28f6"),
"Created": ISODate("2022-05-30T08:46:56.192Z"),
"Options": [
"Some string 3",
"Some string 4"
]
}
]
},
{
"_id": ObjectId("5e29560a2c4c55d421a4e1b4"),
"ResponseItems": [
{
"_id": ObjectId("62bd62ab886b3fde8368ec39"),
"Created": ISODate("2022-06-30T08:45:31.662Z"),
"Options": [
"Some string 1",
"Some string 2"
]
},
{
"_id": ObjectId("62bd6300886b3fde8368ec3f"),
"Created": ISODate("2022-06-30T08:46:56.192Z"),
"Options": [
"Some string 3",
"Some string 4"
]
},
{
"_id": ObjectId("62bd6349886b3fde8368ec46"),
"Created": ISODate("2022-06-30T08:48:09.226Z"),
"Options": null
},
{
"_id": ObjectId("62bd64a88f5b6b24b6de199e"),
"Created": ISODate("2022-06-30T08:54:00.450Z"),
"Options": null
},
{
"_id": ObjectId("62bd64aa8f5b6b24b6de19a7"),
"Created": ISODate("2022-06-30T08:54:02.767Z"),
"Options": null
},
{
"_id": ObjectId("62bd64af8f5b6b24b6de19b1"),
"Created": ISODate("2022-06-30T08:54:07.896Z"),
"Options": null
},
{
"_id": ObjectId("62bd64b38f5b6b24b6de19bc"),
"Created": ISODate("2022-06-30T08:54:11.837Z"),
"Options": null
},
{
"_id": ObjectId("62bd64b78f5b6b24b6de19c8"),
"Created": ISODate("2022-06-30T08:54:15.588Z"),
"Options": [
"Some string 5",
"Some string 6"
]
},
{
"_id": ObjectId("62bd64bd8f5b6b24b6de19d5"),
"Created": ISODate("2022-06-30T08:54:21.494Z"),
"Options": [
"Some string 7"
]
},
{
"_id": ObjectId("62bd654d8f5b6b24b6de331d"),
"Created": ISODate("2022-06-30T08:56:45.487Z"),
"Options": null
}
]
}
]
I want to get a List where several conditions matches, e.g.:
ActionResponse.Id = '5e29560a2c4c55d421a4e1b4' & ActionResponseItem.Created >= ISODate("2022-06-30T08:54:17Z") & ActionResponseItem.Created <= ISODate("2022-06-30T10:09:18.403Z")
and return only the nested elements like:
[
{
"_id": ObjectId("62bd64b78f5b6b24b6de19c8"),
"Created": ISODate("2022-06-30T08:54:15.588Z"),
"Options": [
"Some string 5",
"Some string 6"
]
},
{
"_id": ObjectId("62bd64bd8f5b6b24b6de19d5"),
"Created": ISODate("2022-06-30T08:54:21.494Z"),
"Options": [
"Some string 7"
]
},
{
"_id": ObjectId("62bd654d8f5b6b24b6de331d"),
"Created": ISODate("2022-06-30T08:56:45.487Z"),
"Options": null
}
]
I've tried several queries (with/without aggregation, projection) and so on...
With this query only the first matching element is returned:
Mongo
db.collection.find({
"_id": ObjectId("5e29560a2c4c55d421a4e1b4"),
"ResponseItems": {
"$elemMatch": {
"Created": {
"$gte": ISODate("2022-06-30T08:54:17Z"),
"$lte": ISODate("2022-06-30T10:13:21.754Z")
}
}
}
},
{
"ResponseItems": {
"$elemMatch": {
"Created": {
"$gte": ISODate("2022-06-30T08:54:17Z"),
"$lte": ISODate("2022-06-30T10:13:21.754Z")
}
}
}
})
C#
var filter = Builders<ActionResponse>.Filter.Eq(a => a.Id, id);
var nestedFilter = Builders<ActionResponseItem>.Filter.Gte(x => x.Created, from) &
Builders<ActionResponseItem>.Filter.Lte(x => x.Created, to);
var elements = await _collection
.Find(filter & Builders<ActionResponse>.Filter.ElemMatch(b => b.ResponseItems, nestedFilter))
.Project(Builders<ActionResponse>.Projection
.ElemMatch(c => c.ResponseItems, nestedFilter))
.ToListAsync();
With this the whole document is returned:
Mongo
db.collection.aggregate([
{
"$match": {
"_id": ObjectId("5e29560a2c4c55d421a4e1b4"),
"ResponseItems": {
"$elemMatch": {
"Created": {
"$gte": ISODate("2022-06-30T08:54:17Z"),
"$lte": ISODate("2022-06-30T10:09:18.403Z")
}
}
}
}
}
])
C#
var filter = Builders<ActionResponse>.Filter.Eq(a => a.Id, id);
var nestedFilter = Builders<ActionResponseItem>.Filter.Gte(x => x.Created, from) &
Builders<ActionResponseItem>.Filter.Lte(x => x.Created, to);
var elements = await _collection.Aggregate()
.Match(filter & Builders<ActionResponse>.Filter.ElemMatch(b => b.ResponseItems, nestedFilter))
.ToListAsync();
Maybe there is only a small thing to change and it will work. I hope somebody can help me out on this problem.
MongoDb Playground
THX

something like this should work, you need to do a match, unwind, match and then replace the root
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
var client = new MongoClient();
var itemFilter =
Builders<UnwindResponseItemsActionResponse>.Filter.Gte(x => x.ResponseItems.Created,
new DateTime(2022, 06, 30, 08, 54, 17, DateTimeKind.Utc))
& Builders<UnwindResponseItemsActionResponse>.Filter.Lte(x => x.ResponseItems.Created,
new DateTime(2022, 06, 30, 10, 09, 18, 403, DateTimeKind.Utc));
var actionResponseItems = await client.GetDatabase("test")
.GetCollection<ActionResponse>("actions")
.Aggregate()
.Match(Builders<ActionResponse>.Filter.Eq(x => x.Id, "5e29560a2c4c55d421a4e1b4"))
.Unwind<ActionResponse, UnwindResponseItemsActionResponse>(x => x.ResponseItems)
.Match(itemFilter)
.ReplaceRoot(x => x.ResponseItems)
.ToListAsync();
foreach (var item in actionResponseItems)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Created);
Console.WriteLine();
}
/*
*
62bd64bd8f5b6b24b6de19d5
30/06/2022 08:54:21
62bd654d8f5b6b24b6de331d
30/06/2022 08:56:45
*/
public class UnwindResponseItemsActionResponse
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public ActionResponseItem ResponseItems { get; set; }
}
public class ActionResponse
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public List<ActionResponseItem> ResponseItems { get; set; }
}
public class ActionResponseItem
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public DateTime Created { get; set; }
public List<string> Options { get; set; }
}```

Related

Manipulating Json to remove redundant data c#

I want to return a singular json object with all distinct fields inside that object. The below code generates this json which returns three entries in value where are the same except for the last two fields.
{
"value": [
{
"name": "russ",
"id": "12345",
"grade": 5,
"TestID": "12332",
"testResult": "Pass"
},
{
"name": "russ",
"id": "12345",
"grade": 5,
"TestID": "15474",
"testResult": "Pass"
},
{
"name": "russ",
"id": "12345",
"gradeLevel": 5,
"TestID": "75783",
"testResult": "Fail"
}
]
}
Here is my code that performs a web request to get this data
var result = Helper.DoRequest(requestUrl, null, httpMethod, "");
var jObj = JObject.Parse(result.Last().Value.ToString());
JArray valueList = JArray.Parse(jObj["value"].ToString());
I would like to consolidate that into:
{
"value": [
{
"name": "russ",
"id": "12345",
"grade": 5,
"TestID": "12332",
"testResult": "Pass"
"TestID": "15474",
"testResult": "Pass"
"TestID": "75783",
"testResult": "Fail"
}]
}
This code may be a start. It deserializes the json into classes, and groups the results by Name, ID and Grade (I'm assuming the 'gradelevel' key in the third result was a typo) and then outputs that as Json with the test results as an array (your desired output is not valid Json as it contains duplicate key names):
void Main()
{
var json = json_from_api;
var results = JsonConvert.DeserializeObject<RootObject>(json);
var groupedResults = results.value.GroupBy(r => new { r.id, r.name, r.grade });
var finalResults = groupedResults.Select(g => new
{
g.Key.id,
g.Key.name,
g.Key.grade,
test_results = g.ToList().Select(v => new
{
v.TestID,
v.testResult
}
)});
var output = new {
value = finalResults
};
Console.WriteLine(JsonConvert.SerializeObject(output, Newtonsoft.Json.Formatting.Indented));
}
public class Value
{
public string name { get; set; }
public string id { get; set; }
public int grade { get; set; }
public string TestID { get; set; }
public string testResult { get; set; }
}
public class RootObject
{
public List<Value> value { get; set; }
}
Output:
{
"value": [
{
"id": "12345",
"name": "russ",
"grade": 5,
"test_results": [
{
"TestID": "12332",
"testResult": "Pass"
},
{
"TestID": "15474",
"testResult": "Pass"
},
{
"TestID": "75783",
"testResult": "Fail"
}
]
}
]
}

How do I sort a list based on its child object attributes?

I'm wondering if someone can elucidate a method to sort a list of objects based on a child object's attribute.
I'm working with the following model:
public class Content
{
public string Id { get; set; }
public List<ContentAttribute> Attributes { get; set; }
}
public class ContentAttribute
{
public string Value { get; set; }
public string Id { get; set; }
public string Name { get; set; }
}
Some sample data:
[
{
"Id": "123",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name1"
},
{
"Value": "ghi",
"Id": "2b",
"Name": "name2"
}
]
},
{
"Id": "456",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name2"
},
{
"Value": "def",
"Id": "2b",
"Name": "name3"
}
]
},
{
"Id": "789",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name1"
},
{
"Value": "def",
"Id": "2b",
"Name": "name2"
}
]
}
]
How can I sort the Content objects by the Value of a specific attribute Name? For example, I would like to sort the above data by the Value of 'name2',
meaning the result would be
[
{"Id" : "456"},
{"Id" : "789"},
{"Id" : "123"}
]
Any help is greatly appreciated. (Using c#).
If Attributes always has an element with name name2 and you want an exception if it doesn't then:
var sorted = contents.OrderBy(c => c.Attributes.First(a => a.Name == "name2").Value).ToList();
Or if name2 could be missing and it's not deal breaker then use FirstOrDefault
var sorted = contents.OrderBy(c => c.Attributes.FirstOrDefault(a => a.Name == "name2")?.Value).ToList();

UWP create list using JSON data

OK. I have sent a GET request to SharePoint and received a string back:
"{\"#odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items\",\"value\":[{\"#odata.etag\":\"\\\"a69b1840-239d-42ed-9b20-8789761fb06a,3\\\"\",\"createdDateTime\":\"2018-08-25T22:44:16Z\",\"eTag\":\"\\\"a69b1840-239d-42ed-9b20-8789761fb06a,3\\\"\",\"id\":\"9\",\"lastModifiedDateTime\":\"2018-08-25T22:44:16Z\",\"webUrl\":\"https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/9_.000\",\"createdBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"lastModifiedBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"parentReference\":{},\"contentType\":{\"id\":\"0x0100E19591A4ECA81542AEA41A6AAFED6781\"},\"fields#odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('9')/fields/$entity\",\"fields\":{\"#odata.etag\":\"\\\"a69b1840-239d-42ed-9b20-8789761fb06a,3\\\"\",\"SerialNumber\":\"20180824-1353-DC6-Generator-A\",\"id\":\"9\"}},{\"#odata.etag\":\"\\\"13f60f9e-1bf2-4803-93b9-c45234963d47,3\\\"\",\"createdDateTime\":\"2018-08-25T22:45:55Z\",\"eTag\":\"\\\"13f60f9e-1bf2-4803-93b9-c45234963d47,3\\\"\",\"id\":\"10\",\"lastModifiedDateTime\":\"2018-08-25T22:45:55Z\",\"webUrl\":\"https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/10_.000\",\"createdBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"lastModifiedBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"parentReference\":{},\"contentType\":{\"id\":\"0x0100E19591A4ECA81542AEA41A6AAFED6781\"},\"fields#odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('10')/fields/$entity\",\"fields\":{\"#odata.etag\":\"\\\"13f60f9e-1bf2-4803-93b9-c45234963d47,3\\\"\",\"SerialNumber\":\"20180824-1416-DC6-Generator-B\",\"id\":\"10\"}},{\"#odata.etag\":\"\\\"00024848-0d4e-4ee8-b018-f1653af2a577,3\\\"\",\"createdDateTime\":\"2018-08-25T22:47:30Z\",\"eTag\":\"\\\"00024848-0d4e-4ee8-b018-f1653af2a577,3\\\"\",\"id\":\"11\",\"lastModifiedDateTime\":\"2018-08-25T22:47:30Z\",\"webUrl\":\"https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/11_.000\",\"createdBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"lastModifiedBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"parentReference\":{},\"contentType\":{\"id\":\"0x0100E19591A4ECA81542AEA41A6AAFED6781\"},\"fields#odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('11')/fields/$entity\",\"fields\":{\"#odata.etag\":\"\\\"00024848-0d4e-4ee8-b018-f1653af2a577,3\\\"\",\"SerialNumber\":\"20180824-1438-DC6-Generator-R\",\"id\":\"11\"}},{\"#odata.etag\":\"\\\"7c8e80ed-6fea-408a-9594-2b7b13e3691b,3\\\"\",\"createdDateTime\":\"2018-08-25T23:02:43Z\",\"eTag\":\"\\\"7c8e80ed-6fea-408a-9594-2b7b13e3691b,3\\\"\",\"id\":\"12\",\"lastModifiedDateTime\":\"2018-08-25T23:02:43Z\",\"webUrl\":\"https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/12_.000\",\"createdBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"lastModifiedBy\":{\"user\":{\"email\":\"XXXXX#XXXXX.com\",\"id\":\"b0465821-e891-4f44-9e18-27e875f1b75d\",\"displayName\":\"XXXXX\"}},\"parentReference\":{},\"contentType\":{\"id\":\"0x0100E19591A4ECA81542AEA41A6AAFED6781\"},\"fields#odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('12')/fields/$entity\",\"fields\":{\"#odata.etag\":\"\\\"7c8e80ed-6fea-408a-9594-2b7b13e3691b,3\\\"\",\"SerialNumber\":\"20180824-1456-DC6-Generator-C\",\"id\":\"12\"}}]}"
Which will JObject.Parse to this:
{{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items",
"value": [
{
"#odata.etag": "\"a69b1840-239d-42ed-9b20-8789761fb06a,3\"",
"createdDateTime": "2018-08-25T22:44:16Z",
"eTag": "\"a69b1840-239d-42ed-9b20-8789761fb06a,3\"",
"id": "9",
"lastModifiedDateTime": "2018-08-25T22:44:16Z",
"webUrl": "https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/9_.000",
"createdBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"lastModifiedBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"parentReference": {},
"contentType": {
"id": "0x0100E19591A4ECA81542AEA41A6AAFED6781"
},
"fields#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('9')/fields/$entity",
"fields": {
"#odata.etag": "\"a69b1840-239d-42ed-9b20-8789761fb06a,3\"",
"SerialNumber": "20180824-1353-DC6-Generator-A",
"id": "9"
}
},
{
"#odata.etag": "\"13f60f9e-1bf2-4803-93b9-c45234963d47,3\"",
"createdDateTime": "2018-08-25T22:45:55Z",
"eTag": "\"13f60f9e-1bf2-4803-93b9-c45234963d47,3\"",
"id": "10",
"lastModifiedDateTime": "2018-08-25T22:45:55Z",
"webUrl": "https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/10_.000",
"createdBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"lastModifiedBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"parentReference": {},
"contentType": {
"id": "0x0100E19591A4ECA81542AEA41A6AAFED6781"
},
"fields#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('10')/fields/$entity",
"fields": {
"#odata.etag": "\"13f60f9e-1bf2-4803-93b9-c45234963d47,3\"",
"SerialNumber": "20180824-1416-DC6-Generator-B",
"id": "10"
}
},
{
"#odata.etag": "\"00024848-0d4e-4ee8-b018-f1653af2a577,3\"",
"createdDateTime": "2018-08-25T22:47:30Z",
"eTag": "\"00024848-0d4e-4ee8-b018-f1653af2a577,3\"",
"id": "11",
"lastModifiedDateTime": "2018-08-25T22:47:30Z",
"webUrl": "https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/11_.000",
"createdBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"lastModifiedBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"parentReference": {},
"contentType": {
"id": "0x0100E19591A4ECA81542AEA41A6AAFED6781"
},
"fields#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('11')/fields/$entity",
"fields": {
"#odata.etag": "\"00024848-0d4e-4ee8-b018-f1653af2a577,3\"",
"SerialNumber": "20180824-1438-DC6-Generator-R",
"id": "11"
}
},
{
"#odata.etag": "\"7c8e80ed-6fea-408a-9594-2b7b13e3691b,3\"",
"createdDateTime": "2018-08-25T23:02:43Z",
"eTag": "\"7c8e80ed-6fea-408a-9594-2b7b13e3691b,3\"",
"id": "12",
"lastModifiedDateTime": "2018-08-25T23:02:43Z",
"webUrl": "https://XXXXX.sharepoint.com/sites/GeneratorApp/Lists/GenApp/12_.000",
"createdBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"lastModifiedBy": {
"user": {
"email": "XXXXX#XXXXX.com",
"id": "b0465821-e891-4f44-9e18-27e875f1b75d",
"displayName": "XXXXX"
}
},
"parentReference": {},
"contentType": {
"id": "0x0100E19591A4ECA81542AEA41A6AAFED6781"
},
"fields#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('XXXXX.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/lists('18a725ac-83ef-48fb-a5cb-950ca2378fd0')/items('12')/fields/$entity",
"fields": {
"#odata.etag": "\"7c8e80ed-6fea-408a-9594-2b7b13e3691b,3\"",
"SerialNumber": "20180824-1456-DC6-Generator-C",
"id": "12"
}
}
]
}}
What I ultimately want to do is create a dropdown that is populated with the SerialNumber. When the SerialNumber is selected in the dropdown, it will return the id so that I can then plug that into a GET request to retrieve the appropriate listitems.
I am trying to figure out if I need to do a foreach to create a LIST<> or something else all together.
I do have this class setup, but wasn't sure if I could use it the way I thought I could.
public class Lookup
{
string id { get; set; };
string SerialNumber { get; set; }
}
This is the final working code:
private async void GetButton_Click(object sender, RoutedEventArgs e)
{
var (authResult, message) = await Authentication.AquireTokenAsync();
ResultText.Text = message;
if (authResult != null)
{
var httpClient = new HttpClient();
HttpResponseMessage response;
var request = new HttpRequestMessage(HttpMethod.Get, geturl);
//Add the token in Authorization header
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(content);
var result = JsonConvert.DeserializeObject<SharePointListItems.RootObject>(content);
foreach (var d in result.value)
{
Lookups.Add(new SharePointListItems.Lookup() { id = d.fields.id, SerialNumber = d.fields.SerialNumber });
}
TestComboBox.ItemsSource = Lookups;
}
}
private void TestComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (TestComboBox.SelectedIndex != -1)
{
var mylookupId = (TestComboBox.SelectedItem as SharePointListItems.Lookup).id;// get your id and do further processing here.
ResultText.Text = mylookupId;
}
}
public class SharePointListItems
{
public class Lookup
{
public string SerialNumber { get; set; }
public string id { get; set; }
public override string ToString()
{
return SerialNumber;
}
}
public class Value
{
public Lookup fields { get; set; }
}
public class Fields
{
[JsonProperty("#odata.etag")]
public string ODataETag { get; set; }
...
}
public class RootObject
{
[JsonProperty("#odata.context")]
public string ODataContext { get; set; }
[JsonProperty("#odata.etag")]
public string ODataETag { get; set; }
[JsonProperty("fields#odata.context")]
public string FieldsODataContext { get; set; }
public Fields Fields { get; set; }
public List<Value> value { get; set; }
}
}
There are two way can create model easily.
You can use Web Essentials in Visual Studio, use Edit > Paste special > paste JSON as class, you can easier to know the relation between Json and model.
If you can't use Web Essentials you can instead of use http://json2csharp.com/ online JSON to Model class.
You can try to use those models to carry your JSON Format.
public class Lookup
{
public string SerialNumber { get; set; }
public string id { get; set; }
}
public class Value
{
public Lookup fields { get; set; }
}
public class RootObject
{
public List<Value> value { get; set; }
}
Then you can use obj.value property collection directly.
var obj = JsonConvert.DeserializeObject<RootObject>(jsonData);
foreach (var item in obj.value)
{
//item.fields.id
//item.fields.SerialNumber
}
A good example of how to bind a list of data to Combobox ( dropdown ) is here : https://www.c-sharpcorner.com/article/data-binding-in-xaml-uwp-using-combobox/
in this example the class is a Student with id and Name and it shows how u can show the name in combobox.
I will modify it a little for your scenario but if you want to go in depth than you can visit the provided link above.
This is the class
public class Fields
{
public string SerialNumber { get; set; }
public string id { get; set; }
public override string ToString()
{
return this.SerialNumber; // so that we can just bind to the object and get serial number in the ui.
}
}
Backend for adding items to the List
public sealed partial class MainPage: Page
{
List<Lookup> Lookups = new List<Lookup>();
public MainPage()
{
this.InitializeComponent();
Lookups.Add(new Lookup() {id = 1, SerialNumber = "S1"});
Lookups.Add(new Lookup() {id = 2, SerialNumber = "S2"});
Lookups.Add(new Lookup() {id = 3, SerialNumber = "S3"});
Lookups.Add(new Lookup() {id = 4, SerialNumber = "S4"});
//add as many items here as u want, u can even use a for loop or foreach loop or a Deserializer with newsoft json to get objects from ur json like below.
//var data = JsonConvert.DeserializeObject<RootObject>(jsonData);
//foreach (var d in data.value)
//{
// //d.fields.id //this is how u can get the inside properties.
//}
yourComboBox.ItemSource = Lookups;//setting item source to UI.
}
}
after you successfully bind the data with UI you can use SelectionChanged event of your combobox to do further logic as you require,
void MyComboBox_SelectionChanged(object sender, object args)
{
if(MyCombobox.SelectedIndex!=-1)
{
var mylookupId = (MyCombobox.SelectedItem as Lookup).id;// get your id and do further processing here.
}
}
I think this will be easy when using newtonsoft:
var dynamicObject = JObject.Parse(yourstring);
var list = new List<Lookup>();
//now you have a dynamic object containing an array.
//this should be doable with linq as well.
//note, the type is dynamic
foreach (dynamic thing in dynamicObject )
{
list.Add(new Lookup()
{
id = thing.fields.id,
SerialNumber = thing.fields.SerialNumber
});
}
disclaimer: not tested in any way ;-)

Deserialize json data c#

I want to deserialize JSON response received by Telegram Bot API by getUpdate() method.
JSON data:
{
"ok": true,
"result": [
{
"update_id": 920493886,
"message": {
"message_id": 123,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457375,
"text": "Aata aala"
}
},
{
"update_id": 920493887,
"message": {
"message_id": 124,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457387,
"text": "Jeva tuzyakadun reply aala tevha"
}
},
{
"update_id": 920493888,
"message": {
"message_id": 125,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457443,
"text": "Deposite"
}
},
{
"update_id": 920493889,
"message": {
"message_id": 127,
"from": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k"
},
"chat": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k",
"type": "private"
},
"date": 1472457645,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
},
{
"update_id": 920493890,
"message": {
"message_id": 128,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457670,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
},
{
"update_id": 920493891,
"message": {
"message_id": 130,
"from": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k"
},
"chat": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k",
"type": "private"
},
"date": 1472457848,
"text": "Deposite"
}
},
{
"update_id": 920493892,
"message": {
"message_id": 132,
"from": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k"
},
"chat": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k",
"type": "private"
},
"date": 1472457883,
"text": "Deposite"
}
},
{
"update_id": 920493893,
"message": {
"message_id": 133,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472468407,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
},
{
"update_id": 920493894,
"message": {
"message_id": 134,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472473070,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
}
]
}
I have generated classes from json2csharp
public class From
{
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string username { get; set; }
}
public class Chat
{
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string type { get; set; }
public string username { get; set; }
}
public class Entity
{
public string type { get; set; }
public int offset { get; set; }
public int length { get; set; }
}
public class Message
{
public int message_id { get; set; }
public From from { get; set; }
public Chat chat { get; set; }
public int date { get; set; }
public string text { get; set; }
public List<Entity> entities { get; set; }
}
public class Result
{
public int update_id { get; set; }
public Message message { get; set; }
}
public class RootObject
{
public bool ok { get; set; }
public List<Result> result { get; set; }
}
using newtonsoft to deserialization
var d = Newtonsoft.Json.JsonConvert.DeserializeObject(rcvd_data);
what to do next? how to put this all at work? I am confused please help.
To deserialization use this code:
RootObject ro = JsonConvert.DeserializeObject<RootObject>(rcvd_data);
And in ro you have all data.
EXAMPLE
bool ok = ro.ok;
foreach(Result r in ro.result)
{
int uId = r.update_id;
Message m = r.message;
int msgId = m.message_id;
}
string data = #"{""ok"":true,""result"":[{""update_id"":920493886,...";
RootObject ro = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(data);
foreach (Result result in ro.result)
{
//two example fields
Console.WriteLine("update_id= " + result.update_id);
Console.WriteLine("message text= "+result.message.text);
}
Based on: https://yts.am/api/v2/list_movies.json (Source: https://yts.am/api)
I used: http://json2csharp.com/ to create classes
Copy and paste the result of the get request of postman to json2csharp to automatically create the classes that you need
And once created, i used them on a Service like this:
private string URL = "https://yts.am/api/v2/list_movies.json";
public async Task<List<Movie>> GetMovies()
{
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(URL);
RootObject lista = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json);
List<Movie> todoes = lista.data.movies;
return todoes;
}
I'm using Newtonsoft.Json
Try this way
var d = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(rcvd_‌​data);
then d will contain list of RootObject. By iterating using foreach you can get all the properties of RootObject model

Web Api; Entity Framework; Data returns recursive

im facing a problem with probably selfreference Looping:
Model:
public class ProtectedAccount
{
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Created { get; private set; }
public DateTime? Changed { get; set; }
public bool Disabled { get; set; }
public virtual ICollection<ProtectedAccountMember> Members { get; set; }
public virtual ProtectedAccountType Type { get; set; }
}
public class ProtectedAccountMember
{
public int Id { get; set; }
[StringLength(300)]
public string Name { get; set; }
[Index]
public virtual ProtectedAccount ProtectedAccount { get; set; }
}
Controller:
[ResponseType(typeof(ProtectedAccount))]
[Route("ProtectedAccounts/{id}/Members")]
[HttpGet]
public IHttpActionResult GetProtectedAccountMembers(int id)
{
var protectedAccount = db.ProtectedAccounts.Find(id);
if (protectedAccount == null)
{
return NotFound();
}
return Ok(protectedAccount.Members.ToList());
}
the data wich i receive for an GET seems to Loop recursive through all navigations:
[
{
"ProtectedAccount": {
"Members": [
{
"Id": 2,
"Name": "XXX, XX",
},
{
"Id": 3,
"Name": "XX, XX",
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 1,
"Name": "test",
},
{
"ProtectedAccount": {
"Members": [
{
"Id": 1,
"Name": "test",
},
{
"Id": 3,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXXX",
},
"Id": 2,
"Name": "XX, XX",
},
{
"ProtectedAccount": {a
"Members": [
{
"Id": 1,
"Name": "test",
"SamAccountName": "XXX",
"Disabled": false
},
{
"Id": 2,
"Name": "XX, XX",
"SamAccountName": "XX",
"Disabled": false
}
],
"Type": null,
"Id": 25,
"ObjectGUID": "76bf65e7-af60-4fe8-b3e1-90afbfd65b65",
"Name": "XXX",
},
"Id": 3,
"Name": "XX, XX",
}
]
There is only one "ProtectedAccount" in the database. DO i have to use DTO to overcome this issue? I tried some configuration via the json formatsettings but didnt get any better results.
From your code, you are only returing the protectedAccount.Members, hence you could do a projection query as below
var results = ctx.ProtectedAccountMembers
.Where(member => member.ProtectedAccount.Id == protectedAccount.Id)
.Select(member => new { member.Id, member.Name }).ToList();

Categories