Query CosmosDB with CosmosClient and map to object - c#

Right now I have the following code to query my CosmosDB:
var streamIterator = containerLogs.GetItemQueryStreamIterator("SELECT * FROM mycontainer");
while (streamIterator.HasMoreResults)
{
var results = await streamIterator.ReadNextAsync();
var stream = results.Content;
using var reader = new StreamReader(stream);
string data = await reader.ReadToEndAsync();
// typeof what..?
//var dbDocuments = JsonConvert.DeserializeObject<???>(data);
}
The variable data will contain the following JSON:
{
"_rid": "wDhMAJ9xYHE=",
"Documents": [{
"id": "c05c4eee-32d4-458a-8ae8-d22dd0f93839",
"CustomProperty1": "Value 1",
"CustomProperty2": "Value 2",
"_rid": "wDhMAJ9xYHECAAAAAAAAAA==",
"_self": "dbs\/wDhMAA==\/colls\/wDhMAJ9xYHE=\/docs\/wDhMAJ9xYHECAAAAAAAAAA==\/",
"_etag": "\"00000000-0000-0000-7167-28c107aa01d6\"",
"_attachments": "attachments\/",
"_ts": 1597319093
}],
"_count": 1
}
The Documents part is my actual "domain" model. How can I easily map this back to a list of my domain model class? I used the same class to write to CosmosDB.
The model looks like this
public class MyModel
{
[JsonProperty(PropertyName = "id")]
public Guid Id {get;set;}
public string CustomProperty1 {get;set;}
public string CustomProperty1 {get;set;}
}
So how can I query my CosmosDB so that it returns a list of this class?

Here are some samples that I found helpful. The simpler case is to used the typed GetItemQueryIterator<MyModel>, but there is also a stream deserialization example.

Related

How can I access my nested data using variables C#

I have a json file and I deserialised it as shown in the code below. Some context, dex is a robot and it has information such as battery and so on as shown in the json file below. I want to read the battery status for the robot that the user selected ( robot).
This is my code, currently im only accessing data.dex but i want to change it to whichever data.robot, where robot is a variable
var data = JsonConvert.DeserializeObject<Root>(json);
var robot = queryDetails2.Amr;
var text =$"";
if (data.dex.battery.status == "good")
{
text = $"{queryDetails2.Amr}'s battery is in good condition. ";
}
This is the json file:
{
"dex":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
},
"dex_1":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
},
"dex_2":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
}
}
I wanted to use the GetMethod or the solution as suggested in this question (https://stackoverflow.com/questions/53076743/how-to-access-variable-of-a-nested-functions-in-python[1]).
However, im getting errors like it does not have a method. Now im confused, was it because i used var? but the deserialised method converts the json to an object though..
Anyway, how should i approach this?
Assuming that you have 3 robots with different names: dex, dex_1 and dex_2, you should reorganize your solution to treat the json data as a list of Robots instead of 3 separate variables for each robot.
To do this, first your json should look like this:
{
"robots":[
{
"name":"dex",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
},
{
"name":"dex_1",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
},
{
"name":"dex_2",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
}]
}
Next, update your serialization classes. Add a field called name in the Robot class or whatever class type you currently have for data.dex. In Root, remove the "dex" fields and add a List<Robot>.
public class Root
{
public List<Robot> robots { get; set; }
}
public class Robot
{
public string name { get; set; }
public Job current_job { get; set;}
public Battery battery{ get; set; }
}
Now you can write whatever logic to get the right robot data. Here is an example using System.Linq:
var robotName = "dex_2";
var robotInfo = data.robots.First(x => x.name.Equals(robotName));
var text = $"{robotName}'s battery is in {robotInfo.battery.status} condition.";

How to get element value from response data to json

Im writing an API automation test with RestSharp.Any kind of help will be greatly appreciated!
I'm getting data values from the response & I need to write few values to my json file (which I will use for another test putting them as a body).
I managed to get 1 value from JArray but I need 2 more values and I cant wrap my head around how to do that.
Im attaching my api test code & the data I get from the response + the data I managed to write into my json file.
The value that I managed to get: FsNumber (declared it as financialNumber). What I need to add to the json: subjectName + subjectCode (they will be declared as companyName/companyCode). How do I access "Query" list with SubjectName/SubjectCode?
TEST
var queryResult = client.Execute<object>(request);
var data = JsonConvert.SerializeObject(queryResult.Data);
var jsonParse = JToken.Parse(data);
var fsObject = jsonParse.Value<JToken>("FinanceReportList");
var fsArray = fsObject.Value<JArray>("List");
foreach (var fs in fsArray)
{
var cfn = fs.Value<string>("FsNumber");
var queryObject = new DataQuery
{
financialNumber = cfn,
};
var queryObjectString = JsonConvert.SerializeObject(queryObject);
File.WriteAllText(#"C:\Users\TestAPI\myJsonWithValues.json", queryObjectString);
}
Data I get from the response:
{
"RequestDate": "2021-07-16",
"Message": "Active",
"ProductNumber": 666,
"Language": "EN",
"RequestId": "reqID666",
"Query": {
"SubjectCode": "MY-SUBJECT",
"SubjectName": "MY-NAME"
},
"FinanceReportList": {
"List": [
{
"FsNumber": "MY-NUMBER",
"Year": 2021,
So far I managed to get FsNumber to my myJsonWithValues.json file as this:
{"financialNumber":"MY-NUMBER","companyName":null,"companyCode":null}
What Im trying to do is, my json should look like
{"financialNumber":"MY-NUMBER","companyName":MY-NAME,"companyCode":MY-CODE}
You have to access "Query" object
var fsQuery = jsonParse.Value<JToken>("Query")
and use Children() method to access properties of "Query"
var children = fsQuery.Children();
It is a good practice to implement a class that encapsulates your resonse and deserialize it with JsonConvert.Deserialize eg.
public class Account
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList<string> Roles { get; set; }
}
Account account = JsonConvert.DeserializeObject<Account>(json);
Instead of using JObjects

Web API Json Responce formatting

I've been searching in many places, but I didn't see this type of scenario
My web api response json is like (I have created a model for this) :
{
"var1": 1,
"test1": 2,
"test2": 3
}
but I want my output response like the following :
{
"type": "test",
"query": "query used",
"result": {
"test1": 2,
"test2": 3
},
"error": "if any error"
}
Do I need to create new model ? or any other easy way?
If I need to create new model, how will I assign existing model object values to new model?
You could create a ResponseDTO model and use it on the return of your Json.
public class ResponseDTO<T>
{
public string Type {get;set;}
public string Query {get;set;}
public T Result {get;set;}
public string Error {get;set;}
}
and on your controller, instead of returning your Model, you return an ResponseDTO, like this:
var response = new ResponseDTO<Model>();
response.Result = new Model(); //Do your things here
Doing it like this makes your response generic, so you can use with any kind of model
UPDATE:
For creating a new model without having to copy all properties, you can use and extension method like this:
public class Model()
{
public int Var1 {get;set;}
public string Test1 {get;set;}
public string Test2 {get;set;}
}
public class NewModel(){
public string Test1 {get;set;}
public string Test2 {get;set;}
}
now you create an extension method, for example "ToNewModel", to convert the old model to the new design you want:
public NewModel ToNewModel(this Model model){
var newModel = new NewModel()
newModel.Test1 = model.Test1;
newModel.Test2 = model.Test2;
}
and them, wherever you have your Model object, just call the extension method:
public JsonResult test()
{
var model = new Model()
//{ Fill your model properties }
var response = new ResponseDTO<NewModel>(); //Declare the response of the type of your new design
response.Result = model.ToNewModel();
}

Serialise JSON to C# object into ArrayList of objects

I have the following JSON:
{
"id": "3cf5373c-9181-4639-89f0-bb64b387f961",
"display": "Data 1",
"country": "AU"
}
and I know how to construct the class to serialize it:
[DataContract]
public class myJSONClass
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "display")]
public string Display { get; set; }
[DataMember(Name = "country")]
public string Country { get; set; }
}
and I use the below to serialize:
var url = "http://myJSONAPI/";
var syncClient = new WebClient();
var content = syncClient.DownloadString(url);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(myJSONClass));
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
var jsonData = (myJSONClass)serializer.ReadObject(ms);
}
But how would I go about defining my class if my JSON is like the below?
[
{
"id": "3cf5373c-9181-4639-89f0-bb64b387f961",
"display": "My Data 1",
"country": "AU"
},
{
"id": "8886d2c8-0fd5-49ff-a3e1-7cef9e654514",
"display": "no test",
"country": null
}
]
How would like declare my class?
And how do I serialize it? I cannot use JSON.net as I cannot use newer .Net framework.
[] - It's array. So after deserialization you should get single array object of your class(myJSONClass)
myJSONClass[] deserializedData=deserialize(jsonData);
So if you want to get a deserialized array of objects you should just serialize not a single object but an array(several objects of your class)
But you doing something strange in example because you downloaded string and trying to serialize it. But you received serialized data(string is serialized. Object can be created by deserializing json(or xml) string).
So if you actually received 2 objects in array(as in your last JSON sample) your code should be more like this:
var url = "http://myJSONAPI/";
var syncClient = new WebClient();
var content = syncClient.DownloadString(url);
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(myJSONClass[]));
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
myJSONClass[] jsonObject = (myJSONClass[])serializer.ReadObject(ms);
}
I renamed some variables for better understanding. Also now you deserialize array of your class.
Also i found this thread: Deserialization of array with DataContractJsonSerializer with Windows Store App
But my own advice is to look at NewtonsoftJSON. It's really sweet
http://www.newtonsoft.com/json/help/html/deserializeobject.htm
So then you could achieve everything jus by one line:
myJSONClass[] res = JsonConvert.DeserializeObject<myJSONClass[]>(json_string);
You can do some:
// Use for JavaScriptSerializer
using System.Web.Script.Serialization;
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<myJSONClass> myList = serializer.Deserialize<List<myJSONClass>>(content);
// Use for JsonConvert
using Newtonsoft.Json;
List<myJSONClass> myList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<myJSONClass>>(content);
Hope this help!

Show json data in view in ASP.NET MVC3?

I am developing facebook app in which i am fetching user's friend detail in as
dynamic result = client.Get("me/friends"); //it gives friend's data for id, name
it gives data in
{
"data": [
{
"name": "Steven",
"id": "57564897"
},
{
"name": "Andy",
"id": "8487581"
}
}
Now i would like to parse this data and store it. so that i can use it my way.
I was trying to parse it using JSON.NET and show the data in view as
var model = JsonConvert.DeserializeObject<FriendDetail>(result.data);
in the class :
public class FriendDetail
{
public string id { get; set; }
public string name { get; set; }
public FriendDetail(string i, string n)
{
id = i;
name = n;
}
}
Now so that i can pass the view as "return View(model)"
But its giving me error: The best overloaded method match for 'Newtonsoft.Json.JsonConvert.DeserializeObject<FBApp.Models.FBFriendDetail>(string)' has some invalid arguments
Why this error is occurring ?
Please help me to parse this json data.
Also is there any better way to parse and Store json data and also then show in view ?
Please help
You are trying to deserialize a list of FriendDetail objects into a single FriendDetail object. Try the following:
var jObject = JObject.Parse(result.ToString());
var model = JsonConvert.DeserializeObject<List<FriendDetail>>(jObject["data"].ToString());
EDIT
This is how I tested it:
var result =
#"{
""data"": [
{
""name"": ""Steven"",
""id"": ""57564897""
},
{
""name"": ""Andy"",
""id"": ""8487581""
}]
}";
var jObject = JObject.Parse(result.ToString());
var model = JsonConvert.DeserializeObject<List<FriendDetail>>(jObject["data"].ToString());

Categories