Update list of list of list array mongo update - c#

{
"_id": "111de970-4f3f-4ae6-9d3b-396e60ff50aa",
"ClaimNumber": 111,
"Details": [
{
"Amount": "100",
"Types": [
{
"InvoiceType": "OO",
"Status": "N"
},
{
"InvoiceType": "PP",
"Status": "N"
}
]
},
{
"Amount": "100",
"Types": [
{
"InvoiceType": "OO",
"Status": "N"
},
{
"InvoiceType": "SS",
"Status": "N"
}
]
}
]
}
public class Type
{
public string InvoiceType { get; set; }
public string Status { get; set; }
}
public class Detail
{
public string Amount { get; set; }
public List<Type> Types { get; set; }
}
public class RootObject
{
public string _id { get; set; }
public int ClaimNumber { get; set; }
public List<Detail> Details { get; set; }
}
I Would like to update the values of Types array "Status" = "P" in the Details array when the "_id" column and "Types.InvoiceType" = "OO" value matches.
Please provide me an example on how to achieve in c# using mongo driver.

There you go:
var filter = Builders<RootObject>.Filter.Eq(o => o._id, "111de970-4f3f-4ae6-9d3b-396e60ff50aa");
var update = Builders<RootObject>.Update.Set($"{nameof(RootObject.Details)}.$[].{nameof(Detail.Types)}.$[elem].{nameof(Type.Status)}", "P");
var arrayFilter = new JsonArrayFilterDefinition<BsonDocument>($"{{ 'elem.{nameof(Type.InvoiceType)}': 'OO' }}");
var updateOptions = new UpdateOptions { ArrayFilters = new[] { arrayFilter } };
var result = new MongoClient()
.GetDatabase("database")
.GetCollection<RootObject>("collection")
.UpdateOne(filter, update, updateOptions);

Related

Select Filtering JArray

I have a JArray as follow:
[
{
"id": 5447,
"attributes": {
"alarm": "Mode1"
},
"deviceId": 28
},
{
"id": 5448,
"attributes": {
"alarm": "Mode1"
},
"deviceId": 28
},
{
"id": 5449,
"attributes": {
"alarm": "Mode2"
},
"deviceId": 28
}
]
how to filter by ["attributes"]["alarm"] == "Mode1" ?
I tried:
JArray _new_ja = __ja_alarm.Where(p => p["attributes"]["alarm"].ToString() == "Mode1");
it returns null?
You could just deserialize it
Given
public class Attributes {
public string alarm { get; set; }
}
public class Model {
public int id { get; set; }
public Attributes attributes { get; set; }
public int deviceId { get; set; }
}
Usage
var model = JsonConvert
.DeserializeObject<List<Model>>(input)
.FirstOrDefault(x => x.attributes.alarm == "Mode1");
Or
var result = JArray
.Parse(input)
.FirstOrDefault(x => (string) x["attributes"]["alarm"] == "Mode1")
.ToObject<Model>();
Use Where instead of FirstOrDefault If you want a list of matches

c# how to count the amount of json values

So, I am trying to count the amount of values in JSON using c#. The Json is:
{
"Someid": 657442,
"roles": [
{
"id": 3892751,
"name": "Guest",
"rank": 0,
"memberCount": 0
},
{
"id": 3892750,
"name": "Fanz!<3",
"rank": 1,
"memberCount": 0
},
{
"id": 3892749,
"name": "Lead-Singer",
"rank": 254,
"memberCount": 0
},
{
"id": 3892748,
"name": "Drums",
"rank": 255,
"memberCount": 0
}
]
}
I want to count the amount "roles". The JSON is just in a string variable. Help?
You can either use like this:
var token = JToken.Parse(input);
var roles= token.Value<JArray>("roles");
var count = roles.Count;
Or you can also use JsonPath:
var token = JToken.Parse(input);
var count = token.SelectTokens("$.roles[*]").Count();
But ideally, you should be serilizing into an object and then using the properties to get the Count:
public class Role
{
public int id { get; set; }
public string name { get; set; }
public int rank { get; set; }
public int memberCount { get; set; }
}
public class MyObject
{
public int Someid { get; set; }
public List<Role> roles { get; set; }
}
var item = JsonConvert.DeserializeObject<MyObject>(input);
var count = item.roles.Count;

CoinPayment GetExchangeRates Api Response Hnadling Issue

I am working on a Coinpayment.net api implementation.I am trying to get the CoinExhange Rates by Using GetExchangeRate Method, I am unable to Parese the Response. I want to get the list of all the coins rate but i dont know which response class i can use to and how for getting the list of response.
Following is the Implementation i tried.
string result = string.Empty;
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(_ApiReferenceLink);
var response = await client.GetAsync("GetExchangeRates");
if (response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
ExchangeRatesResponse datalist = JsonConvert.DeserializeObject<ExchangeRatesResponse>(result);
return Json(new { Message = "Your Transaction Has Been Completed Successfully!" }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { ErrorMessage = "Your Transaction Has Not Been Completed. Try Again Later!" }, JsonRequestBehavior.AllowGet);
}
}
The above code dint gave me the response in object so that i can loop through and get the required coins price.
This is the responce that api will return to me i want to convert it to object so that i can access it using object.
{
"error": "ok",
"result": {
"BTC": {
"is_fiat": 0,
"rate_btc": "1.000000000000000000000000",
"last_update": "1375473661",
"tx_fee": "0.00100000",
"status": "online",
"name": "Bitcoin",
"confirms": "2",
"capabilities": [
"payments",
"wallet",
"transfers",
"convert"
]
},
"LTC": {
"is_fiat": 0,
"rate_btc": "0.018343387500000000000000",
"last_update": "1518463609",
"tx_fee": "0.00100000",
"status": "online",
"name": "Litecoin",
"confirms": "3",
"capabilities": [
"payments",
"wallet",
"transfers",
"convert"
]
},
"USD": {
"is_fiat": 1,
"rate_btc": "0.000114884285404190000000",
"last_update": "1518463609",
"tx_fee": "0.00000000",
"status": "online",
"name": "United States Dollar",
"confirms": "1",
"capabilities": []
},
"CAD": {
"is_fiat": 1,
"rate_btc": "0.000091601308947890000000",
"last_update": "1518463609",
"tx_fee": "0.00000000",
"status": "online",
"name": "Canadian Dollar",
"confirms": "1",
"capabilities": []
},
"MAID": {
"is_fiat": 0,
"rate_btc": "0.000049810000000000000000",
"last_update": "1518463609",
"tx_fee": "0.00000000",
"status": "online",
"name": "MaidSafeCoin",
"confirms": "2",
"capabilities": [
"payments",
"wallet"
]
},
"XMR": {
"is_fiat": 0,
"rate_btc": "0.028198593333333000000000",
"last_update": "1518463609",
"tx_fee": "0.01000000",
"status": "online",
"name": "Monero",
"confirms": "3",
"capabilities": [
"payments",
"wallet",
"transfers",
"dest_tag"
]
},
"LTCT": {
"is_fiat": 0,
"rate_btc": "1.000000000000000000000000",
"last_update": "1375473661",
"tx_fee": "0.00100000",
"status": "online",
"name": "Litecoin Testnet",
"confirms": "0",
"capabilities": [
"payments",
"wallet",
"transfers"
]
}
}
}
The Responce Object Class that i used is:
public class ExchangeRatesResponse
{
public List<ExchangeRateItem> ItemsList { get; set; }
}
public class ExchangeRateItem
{
public string is_fiat { get; set; }
public decimal rate_btc { get; set; }
public int last_update { get; set; }
public string name { get; set; }
public int Confirms { get; set; }
}
Any help would be greatlly appreciated.
Thanks
Your C# object's structure does not match the JSON. Nothing will ever deserialise to a List<> because the JSON contains only objects, and not arrays (with the exception of "capabilities", but you don't seem to be interested in that bit). result is a single object containing several properties such as BTC, LTC, USD etc. So you need to make something which matches that.
Off the top of my head (untested), this should be more like it:
public class ExchangeRatesResponse
public ExchangeRateResult result { get; set; }
public string error { get; set; }
}
public class ExchangeRateResult
{
public ExchangeRateItem BTC { get; set; }
public ExchangeRateItem LTC { get; set; }
public ExchangeRateItem USD { get; set; }
public ExchangeRateItem CAD { get; set; }
public ExchangeRateItem MAID { get; set; }
public ExchangeRateItem XMR { get; set; }
public ExchangeRateItem LTCT { get; set; }
}
public class ExchangeRateItem
{
public string is_fiat { get; set; }
public decimal rate_btc { get; set; }
public int last_update { get; set; }
public string name { get; set; }
public int confirms { get; set; }
}
You can parse through this using LINQ. Add the directive below to your class.
using System.Linq;
This method will return the list you were requesting.
public List<ExchangeRateItem> ParseAndReturnExchangeRateItemList(string jsonString)
{
//parse JSON and grab it's children.
var JSONobj = JObject.Parse(jsonString).Children();
//turn into dictionary of property name and value
var dictionary = JSONobj
.Select(s => (s as JProperty))
.ToDictionary(u => u.Name, v => v.Value);
var ExchangeRateToExchangeDetailsDictionary =
//grab result, maybe in another line grab error to make sure none exist.
dictionary["result"]
.Select(s => (s as JProperty))
.ToDictionary(u => u.Name
,v => JsonConvert.DeserializeObject<ExchangeRateItem>(v.Value.ToString()));
//you iterate through your dictionary like this
foreach (var kvp in ExchangeRateToExchangeDetailsDictionary)
{
//this is just string key of the exchangeRateCode
var exchangeRate = kvp.Key;
//this will return the ExchangeRateItem object.
var exchangeRateDetails = kvp.Value;
}
//you can also get the ExchangeRateItem object per exchangeRate like this
var giveMeUSExchangeRate = ExchangeRateToExchangeDetailsDictionary["USD"];
//if you need to just return a list of ExchangeRateItem objects you can do this
List<ExchangeRateItem> listOfExchangeRateItem = ExchangeRateToExchangeDetailsDictionary.Values.ToList();
return listOfExchangeRateItem;
}
You can call it and feed it your JSON result.
if (response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
ExchangeRatesResponse datalist = ParseAndReturnExchangeRateItem(result);
return Json(new { Message = "Your Transaction Has Been Completed Successfully!" }, JsonRequestBehavior.AllowGet);
}

Create json object with multiple array in c#

I want to create JSON object with following format:-
{
"result": [
{
"name": "John",
"address": "US",
},
{
"name": "Josh",
"address": "Japan",
}
],
"error": [
{
"message": "error-message"
}
],
"success": [
{
"message": "success-message"
}
]
}
I have tried the following, but it doesn't help me.
dynamic record = new { result = new {name="", address=""},
error = new {message=""},
success = new {message=""} };
Update 1:-
Here is my code:-
List addressList = new List();
// Loop over items within the container and URI.
foreach (var item in items)
{
dynamic record = new { result = new object[] {
new {name = item.name, address = item.address} } };
addressList.Add(record);
}
Result:-
[ {
"result": [
{
"name": "John",
"address": "US"
}
]
},
{
"result": [
{
"name": "Jack",
"address": "CA"
}
]
}
]
Expected json result:-
[{
"result": [{
"name": "John",
"address": "US"
}]
},
{
"result": [{
"name": "Jack",
"address": "CA"
}],
"error": [{
"message": "error-message"
}],
"success": [{
"message": "success-message"
}]
}
]
How do I update my code to get above expected json result?
You...create arrays. You're not doing that. You're creating individual objects.
Something along the lines of:
dynamic record = new {
result = new object[] {
new {name = "John", address = "US"},
new {name = "Josh", address = "Japan"}
},
error = new object[] /*...*/,
success = new object[] /*...*/
};
If you want exactly JSON, then newtonsoft.Json makes it easier:
Json json = new Json();
json.result = new object[] {
new {name = "John", address = "US"},
new {name = "Josh", address = "Japan"}
};
// json.error = ... and so on
string output = JsonConvert.SerializeObject(product);
The output you will have is:
{
"result": [
{
"name": "John",
"address": "US",
},
{
"name": "Josh",
"address": "Japan",
}
],
"error": [
{
...
}
]
}
To deserialize it back, use:
Json deserializedJson = JsonConvert.DeserializeObject<Json>(output);
you are not creating an array
if you want to create JSON arrays from c# you have to use the following POCO
public class Result
{
public string name { get; set; }
public string address { get; set; }
}
public class Error
{
public string message { get; set; }
}
public class Success
{
public string message { get; set; }
}
public class RootObject
{
public List<Result> result { get; set; }
public List<Error> error { get; set; }
public List<Success> success { get; set; }
}
and then use Json.net
var json = JsonConvert.SerializeObject( "your instance of the root Object")
//You need to make this class structure first
public class Response
{
public List<Result> result { get; set; }
public List<Error> error { get; set; }
public List<Success> success { get; set; }
}
public class Result
{
public string name { get; set; }
public string address { get; set; }
}
public class Error
{
public string message { get; set; }
}
public class Success
{
public string message { get; set; }
}
// And then you can use it like this
var response = new Response()
{
result = new List<Result>
{
new Result() {name = "Jhon", address = "US"},
new Result() {name = "Jhon", address = "US"},
},
error = new List<Error>()
{
new Error() {message = "error-message 1"},
new Error() {message = "error-message 2"}
},
success = new List<Success>()
{
new Success(){message = "success-message 1"},
new Success(){message = "success-message 2"},
}
};
The Model Class
public class MegaMenu
{
public int department_id { get; set; }
public string department_name { get; set; }
public List<SectionListData> sectionListData { get; set; }
}
public class SectionListData
{
public int section_id { get; set; }
public string section_name { get; set; }
public List<ItemHeadList> itemHeadList { get; set; }
}
public class ItemHeadList
{
public int item_head_id { get; set; }
public string item_name { get; set; }
}
public class WrapperMegaMenu
{
public List<MegaMenu> megaMenuList { get; set; }
public string error { get; set; }
}
The Services
dept_result is the array of all department,section_result is the array of all section,Item_result is the array of all items
List<MegaMenu> listmenu = new List<MegaMenu>();
foreach (var each_dept in dept_result)
{
MegaMenu megaMenu = new MegaMenu();
megaMenu.department_id = each_dept.shopdepartment_id;
megaMenu.department_name = each_dept.name_en;
var temSectionList = section_result
.Where(item => item.shopdepartment_id == each_dept.shopdepartment_id).ToList().Select(sectionData => new SectionListData
{
section_id = sectionData.shopsection_id,
section_name = sectionData.name_en,
itemHeadList = Item_result.Where(itemHead => itemHead.shopsection_id == sectionData.shopsection_id).ToList().Select(itemHeadData => new ItemHeadList {
item_head_id = itemHeadData.item_head_id,
item_name = itemHeadData.name_en
}).ToList()
}).ToList();
megaMenu.sectionListData = temSectionList;
listmenu.Add(megaMenu);
}
//wrapperDept.departmentList = dept_result.ToList();
wrapper.megaMenuList = listmenu.ToList();
Result
{
"megaMenuList": [
{
"department_id": 71,
"department_name": "Baby's Hygiene",
"sectionListData": [
{
"section_id": 56,
"section_name": "Diapers",
"itemHeadList": []
},
{
"section_id": 57,
"section_name": "Wipes",
"itemHeadList": [
{
"item_head_id": 142,
"item_name": "Telivision"
}
]
}
]
}
]
}

Use Linq or C# to parse Json

I am getting familiar with C# and Linq and appreciate any help. It should be easy for someone who works with it. I have a Json object that returns contact information. I also have a list of ids. I need to compare the list to the Json object and wherever the value in the list matches the userclientcode in the Json object, I need to extract the following information (only for the matches):
clienttaxonomy (if not empty)
fullname (if not empty)
[0]contactdata ( -> email if not null or empty)
[1]contactdata (-> address if not null or empty)
[2]contactdata (-> phone number if not null or empty)
First List
var fileContactIds = new List<string> { "5678765", "2135123", "12341234", "341234123", "12341234123", "2341234123", "341234123", "123412341", "13342354",
"12342341", "123412322", "163341234", "2345234115", "8967896", "75626234 };
JSON object returned with:
return JsonConvert.DeserializeObject<RelatedContacts>(json)?.list;
This is the Json object:
[![Json object][1]][1]
This is the Json string (unescaped):
{
"type": "com.kurtosys.api.userprofile.domain.RelatedContactList",
"list": [{
"objectlistid": 5678765,
"objectlisttypeid": 4567876,
"objectlistname": "ALL.National",
"clienttaxonomyid": 765677,
"clienttaxonomy": "National Wholesaler",
"order": 1,
"contacts": [{
"personid": 7654345678,
"fullname": "Person Jallo",
"userid": 876567,
"userclientcode": "341234123",
"contactdetails": [{
"contactid": 8765567,
"contacttypeid": 4565,
"contactdata": "person.contact#site.com"
}, {
"contactid": 876545678,
"contacttypeid": 4565,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 87654567,
"contacttypeid": 4584,
"contactdata": "410-413-2640"
}]
}]
}, {
"objectlistid": 765678,
"objectlisttypeid": 40400461,
"objectlistname": "RM.Internal",
"clienttaxonomyid": 7567898,
"clienttaxonomy": "Internal Regional Wholesaler",
"order": 2,
"contacts": [{
"personid": 56789876,
"fullname": "Jackson Man",
"userid": 876567,
"userclientcode": "1012275",
"contactdetails": [{
"contactid": 309598309,
"contacttypeid": 76546,
"contactdata": "mister.jackson##site.com.com"
}, {
"contactid": 876567,
"contacttypeid": 4581,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 876567,
"contacttypeid": 2342,
"contactdata": "123-413-2604"
}]
}]
}, {
"objectlistid": 309571364,
"objectlisttypeid": 40400461,
"objectlistname": "RM.External",
"clienttaxonomyid": 309580710,
"clienttaxonomy": "External Regional Wholesaler",
"order": 3,
"contacts": [{
"personid": 302736188,
"fullname": "Phal Sumi",
"userid": 303826019,
"userclientcode": "163341234",
"contactdetails": [{
"contactid": 309598253,
"contacttypeid": 2342,
"contactdata": "misters.emailas#site.com"
}, {
"contactid": 309611930,
"contacttypeid": 2342,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 34234132,
"contacttypeid": 3422,
"contactdata": "342-803-1793"
}]
}]
}]
}
How do I
1] Select using Linq and Lambdas and put in a list fullname, email, address etc from the deserialized object ?
2]compare with first list and only transfer those items where the userclientcode == the number in list A.
I have tried:
var query5 = relatedContact.Where(s => s.objectlistid == Convert.ToInt64(contacts.Select(t => t.id)))
var selected = relatedContact.Where(p => p.contacts
.Any(a => fileContactIds.Contains(p.contacts))
.ToList();
var query2 = relatedContact.Where(s => s.objectlistid == Convert.ToInt64(contacts.Select(t => t.id)))
.Select(s => new
{
Description = s.clienttaxonomy,
Fullname = s.contacts[0].fullname,
Email = s.contacts[0].contactdetails[0].contactdata,
Address = s.contacts[0].contactdetails[1].contactdata,
PhoneNumber = s.contacts[0].contactdetails[2].contactdata
});
But don't really know what I'm doing it seems. Any suggestions on how to get the required sections ? I think part of the reason is that the contactdata is a list.
Thanks all
You can create a classes for the desearlization of JSON Object like this
public class Rootobject
{
public string type { get; set; }
public List[] list { get; set; }
}
public class List
{
public int objectlistid { get; set; }
public int objectlisttypeid { get; set; }
public string objectlistname { get; set; }
public int clienttaxonomyid { get; set; }
public string clienttaxonomy { get; set; }
public int order { get; set; }
public Contact[] contacts { get; set; }
}
public class Contact
{
public long personid { get; set; }
public string fullname { get; set; }
public int userid { get; set; }
public string userclientcode { get; set; }
public Contactdetail[] contactdetails { get; set; }
}
public class Contactdetail
{
public int contactid { get; set; }
public int contacttypeid { get; set; }
public string contactdata { get; set; }
}
And then to extract the selected information we can also create a another class like
public class ExtractedInfo
{
public string ocClientTaxonomy { get; set; }
public string ocFullName { get; set; }
public CTDetails ocContactDetails { get; set; }
}
public class CTDetails
{
public string ocCTAddress { get; set; }
public string ocCTEmail { get; set; }
public string ocCTPhoneNumber { get; set; }
}
Now we have to find all the data from JSON
var fileContactIds = new List<string> { "5678765", "2135123", "12341234", "341234123", "12341234123", "2341234123", "341234123", "123412341", "13342354", "12342341", "123412322", "163341234", "2345234115", "8967896", "75626234" };
//Read JSON from txt file. You can do it by your way
string myjson = File.ReadAllText("Some.txt");
string ctphno, ctadd, ctemail, cltax, ctfullname;
List<ExtractedInfo> ei = new List<ExtractedInfo>();
CTDetails ctdtl = new CTDetails();
ExtractedInfo eiex = new ExtractedInfo();
//Deserialize the JSON string to Object.
Rootobject AllData = JsonConvert.DeserializeObject<Rootobject>(myjson);
//Finding all data in List Class
foreach(List lst in AllData.list)
{
cltax = lst.clienttaxonomy; // you can directly put eiex.ocClientTaxonomy = lst.clienttaxonomy;
foreach(Contact ct in lst.contacts)
{
//To check if value in the list matches the objectlistid in the Json object
if(fileContactIds.Contains(lst.objectlistid.ToString()))
{
ctfullname = ct.fullname; // you can directly put eiex.ocFullName = ct.fullname;
foreach(Contactdetail ctd in ct.contactdetails)
{
//Here we are trying to find the Match for Email.
if(Regex.IsMatch(ctd.contactdata, #"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase))
{
ctemail = ctd.contactdata;
ctdtl.ocCTEmail = ctemail;
}
//Here We trying to find the match for Phone Number.
else if(Regex.IsMatch(ctd.contactdata, #"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}", RegexOptions.IgnoreCase))
{
ctphno = ctd.contactdata;
ctdtl.ocCTPhoneNumber = ctphno;
}
//If NOthing matches than it might be address (Assumed)
else
{
ctadd = ctd.contactdata;
ctdtl.ocCTAddress = ctadd;
}
}
eiex.ocFullName = ctfullname;
}
}
eiex.ocClientTaxonomy = cltax;
eiex.ocContactDetails = ctdtl;
ei.Add(eiex);
}
Hope this helps and fit in your requirements.

Categories