C# Json LinQ - Build Json String Using Loop - c#

I am trying to produce a Json string that looks like this:
{
"fromAddress": {
"streetLines": [
"100 Test St",
"Ste 100"
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
},
"toAddress": {
"streetLines": [
"101 Test St",
null
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
},
"packageDimensions": [
{
"weight": 20.0,
"length": "18",
"width": "12",
"height": "13"
},
{
"weight": 20.0,
"length": "18",
"width": "12",
"height": "13"
},
{
"weight": 20.0,
"length": "18",
"width": "12",
"height": "13"
}
]
}
I've gotten this far with my code:
var json = new
{
fromAddress = new
{
streetLines = new[]
{
fromAddress1,
fromAddress2
},
city = fromCity,
stateOrProvinceCode = fromState,
postalCode = fromZip,
countryCode = fromCountry
},
toAddress = new
{
streetLines = new[]
{
toAddress1,
toAddress2
},
city = toCity,
stateOrProvinceCode = toState,
postalCode = toZip,
countryCode = toCountry
},
};
That produces the following, which is lacking the pack dimensions:
{
"fromAddress": {
"streetLines": [
"100 Test St",
"Ste 100"
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
},
"toAddress": {
"streetLines": [
"101 Test St",
null
],
"city": "Orlando",
"stateOrProvinceCode": "FL",
"postalCode": "32819",
"countryCode": "US"
}
}
My data for the pack dimensions are stored thusly:
List<double> weight
string length
string width
string height
Multiple values for weight are passed in with the List, the dimensions are constants.
I need to find a way to add the pack dimensions, iterating through the weight List to do so. But I'm not sure how to approach it, adding a loop in the Json build doesn't work in any way.
I would appreciate any advice on getting the data iteration that I need. Thanks.

You have to add LINQ expression with projection:
var json = new
{
fromAddress = new
{
streetLines = new[]
{
fromAddress1,
fromAddress2
},
city = fromCity,
stateOrProvinceCode = fromState,
postalCode = fromZip,
countryCode = fromCountry
},
toAddress = new
{
streetLines = new[]
{
toAddress1,
toAddress2
},
city = toCity,
stateOrProvinceCode = toState,
postalCode = toZip,
countryCode = toCountry
},
packageDimensions = weight.Select(w => new
{
weight = w,
length = length,
width = width,
height = height
})
.ToArray()
};

Related

Array name is random every time C# complex Json

This is the Json I am working with:
{
"field_1": 918237,
"field_2": "test",
"field_3": 918237,
"field_4": [
{
"Type": "test",
"field_5": {
"id": "aasd812736",
"time": "2018-03-29T20:34:33.910Z",
"last_time": "2022-11-16T17:30:54.579Z",
"ext": 123,
"exp": 5,
"id_full": "aasd8127367618253172",
"moreId": 87162387,
"version": "v1.5",
"items": {
"RANDOM ID_1": {
"template": "ineedthis_1",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1",
"owned": [
" lvl 1 ",
" lvl 2 ",
" lvl 3 ",
" lvl 4 ",
" lvl 5 "
]
}
}
},
"RANDOM ID_2": {
"template": "ineedthis_2",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1"
}
}
},
"RANDOM ID_3": {
"template": "ineedthis_3",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1",
"owned": [
" lvl 2 ",
" lvl 3 ",
" lvl 4 ",
" lvl 5 "
]
}
}
},
"RANDOM ID_4": {
"template": "ineedthis_4",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1"
}
}
},
"RANDOM ID_5": {
"template": "ineedthis_5",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1"
}
}
},
"RANDOM ID_6": {
"template": "ineedthis_6",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1"
}
}
},
"RANDOM ID_7": {
"template": "ineedthis_7",
"attributes": {
"lvl_at": 1,
"has_at": true,
"variants": {
"channel": "progressive",
"active": "lvl1",
"owned": [
" lvl 2 ",
" lvl 3 "
]
}
}
}
}
},
"stats": [
{
"attributes": {
"lifetime": 100,
"book": false,
"past_experience": [
{
"seas_id": 3,
"seas_wi": 100,
"seas_lv": 40,
"book_lv": 30
},
{
"seas_id": 4,
"seas_wi": 310,
"seas_lv": 5,
"book_lv": 30
},
{
"seas_id": 5,
"seas_wi": 150,
"seas_lv": 51,
"book_lv": 32
}
]
}
}
]
}
]
}
So basically, the RANDOM ID_1 to 7 are randomly generated everytime by the API, I want to get the value from the template to a string for each one of the IDs and if there is a variant I want to get the maximum variant that is available, when available(Ex. ID_7 has max lvl 3 but ID_3 has max lvl 5).
It would be so much easier if the array name was not random for these. I've been searching the whole day on stackoverflow and other websites but can't seem to find anyone with a similar issue to this.
If you have answered this question before, please send me the link. Would appreciate it a lot!
I've tried
var user = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(user.template);
But this way it returns me the null exception for the user . Also thinking that I cannot check the variants this way.
Instead of dynamic , I prefer to use Parse
var items = ((JObject)JObject.Parse(json)["field_4"][0]["field_5"]["items"]);
List<Result> result = items.Properties().Select(x => new Result
{
Id = x.Name,
Template = (string)x.Value["template"],
MaxLevel = x.Value["attributes"]["variants"]["owned"] == null ?
"N/A" : x.Value["attributes"]["variants"]["owned"][x.Value["attributes"]["variants"]["owned"].Count() - 1].ToString().Trim()
}).ToList();
public class Result
{
public string Id { get; set; }
public string Template { get; set; }
public string MaxLevel { get; set; }
}
or you can use an anonymous object instead of class
result
[
{
"Id": "RANDOM ID_1",
"Template": "ineedthis_1",
"MaxLevel": "lvl 5"
},
{
"Id": "RANDOM ID_2",
"Template": "ineedthis_2",
"MaxLevel": "N/A"
},
{
"Id": "RANDOM ID_3",
"Template": "ineedthis_3",
"MaxLevel": "lvl 5"
},
{
"Id": "RANDOM ID_4",
"Template": "ineedthis_4",
"MaxLevel": "N/A"
},
{
"Id": "RANDOM ID_5",
"Template": "ineedthis_5",
"MaxLevel": "N/A"
},
{
"Id": "RANDOM ID_6",
"Template": "ineedthis_6",
"MaxLevel": "N/A"
},
{
"Id": "RANDOM ID_7",
"Template": "ineedthis_7",
"MaxLevel": "lvl 3"
}
]

Restsharp JSON response search

I need to search the following JSON response. I have no control over how the JSON is returned to me or how it is nested. I am using Restsharp by default, but I am open to whatever method helps me accomplish the task.
{
"response": [
{
"id": 1008,
"brandId": 74,
"collectionId": 32,
"productTypeId": 1,
"nominalCodeStock": "1200",
"nominalCodePurchases": "5002",
"nominalCodeSales": "4000",
"seasonIds": [
],
"identity": {
"sku": "SKU0001",
"isbn": "0684843285",
"ean": "ISNB09712345",
"upc": "5778400001",
"barcode": "738737638"
},
"productGroupId": 0,
"featured": false,
"stock": {
"stockTracked": true,
"weight": {
"magnitude": 0.7
},
"dimensions": {
"length": 2,
"height": 12,
"width": 5,
"volume": 120
}
},
"financialDetails": {
"taxCode": {
"id": 7,
"code": "T20"
}
},
"salesChannels": [
{
"salesChannelName": "Brightpearl",
"productName": "Product B",
"productCondition": "new",
"categories": [
{
"categoryCode": "276"
},
{
"categoryCode": "295"
}
],
"description": {
"languageCode": "en",
"text": "Some description",
"format": "HTML_FRAGMENT"
},
"shortDescription": {
"languageCode": "en",
"text": "Some short description",
"format": "HTML_FRAGMENT"
}
}
],
"composition": {
"bundle": false
},
"variations": [
{
"optionId": 1,
"optionName": "Colour",
"optionValueId": 1,
"optionValue": "Black"
},
{
"optionId": 3,
"optionName": "Colour",
"optionValueId": 9,
"optionValue": "Black"
}
],
"warehouses": {
"2": {
"defaultLocationId": 5,
"reorderLevel": 1,
"reorderQuantity": 0
},
"3": {
"defaultLocationId": 0,
"reorderLevel": 1,
"reorderQuantity": 1
}
},
"createdOn": "2015-01-08T17:57:18.000Z",
"updatedOn": "2015-04-01T13:17:58.000Z",
"reporting": {
"categoryId": 353,
"subcategoryId": 369,
"seasonId": 2
},
"primarySupplierId": 202,
"status": "LIVE",
"salesPopupMessage": "Offer the extended warranty",
"version": 1192098806000
}
]
}
Specifically I need to retrieve the categoryCode values. I'm lost on this one. Any direction is much appreciated.

NEST Elastic search empty values in Documents result

Elastic search noob question.
After reading some questions on SO I figured out to POST some data to my Index but I'm having some trouble getting back results.
I'm getting one document (as expected) but all properties are empty. The number of bytes 740 match the number of bytes received in Postman. I suspect the data isn't mapped right somehow..
Code:
var client = CreateCloudClient();
var indexName = "index-b";
var mustClauses = new List<QueryContainer>();
mustClauses.Add(new WildcardQuery
{
Field = new Field("FirstName"),
Value = "*ralf*"
});
var searchRequest = new SearchRequest<ProfileEntity>(indexName)
{
Query = new BoolQuery { Must = mustClauses }
};
var searchResponse = await client.SearchAsync<ProfileEntity>(searchRequest);
if (searchResponse.Hits.Any())
{
var person = searchResponse.Hits.First();
}
Debugger result
When using Postman:
GET ../westeurope.azure.elastic-cloud.com:9243/index-b/_search
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"FirstName": "*ralf*"
}
}
]
}
}
}
I'm getting:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "index-b",
"_type": "_doc",
"_id": "0ec623e7-3837-4e83-808d-fed01398d1ab",
"_score": 1.0,
"_source": {
"Id": 0,
"ProfileId": "0ec623e7-3837-4e83-808d-fed01398d1ab",
"FirstName": "Ralf",
"LastName": "de K",
"BirthDate": "1999-09-19T00:00:00Z",
"BirthPlace": "Zwolle",
"BirthPlaceLocation": {
"Longitude": 41.9074,
"Latitude": -78.7911
},
"City": "Zwolle",
"Email": "email#example.org",
"ObjectIdentifier": "0ec623e7-3837-4e83-808d-fed01398d1ab",
"MobileNumber": "06123123123",
"Height": 2,
"BodyBuild": 0,
"Ethnicity": 8,
"Education": 3,
"Gender": 2,
"Created": "0001-01-01T00:00:00",
"Updated": "0001-01-01T00:00:00"
}
}
]
}
}
It was my own mistake. I used ElasticLowLevelClient to add a new index and I (probably) should have used ElasticClient because the first adds the index with pascal casing and the latter camel casing. Could be a config/setting but usinf ElasticClient fixes my problem.

JToken get a specific value

I have following JToken output. How can I retrieve the 'value' here from TenantID which should be 1 in this case?
{[
{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}
]}
This is my current code :
JToken value;
if (usr.Profile.TryGetValue("tenantid", out value))
{
JObject inner = value["value"].Value<JObject>(); //not working with null error
User.TenantID = (string)value;
}
User.obj = usr.Profile;
EDIT - please find below the complete JToken output :
{[
{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}
]}
Count: 1
First (Newtonsoft.Json.Linq.JContainer): {{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}}
First (Newtonsoft.Json.Linq.JToken): {{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}}
HasValues: true
IsReadOnly: false
Last (Newtonsoft.Json.Linq.JContainer): {{
`"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}}
Last (Newtonsoft.Json.Linq.JToken): {{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}}
Next: (null)
Parent: {"tenantid": [
{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}
]}
Path: "tenantid"
Previous: (null)
Static members:
Non-public members:
IEnumerator:
Root: {{
"name": "Rx Sidhu",
"given_name": "Rx",
"family_name": "Sidhu",
"locale": "en_US",
"emails": [
"ranxdeep#xxx.com",
"ranxdeep#xxx.com",
"ranxdeep#hx.com"
],
"nickname": "ranxdeep#xxx.com",
"email": "ranxdeep#xxx.com",
"picture": "https://apis.live.net/v5.0/f1xxxxxx/picture",
"roles": [
"Account Admin",
"Admin"
],
"tenantid": [
{
"value": 1,
"metadata": {
"userType": 0,
"flags": 8,
"type": {
"type": "INT4",
"name": "Int",
"id": 56
},
"colName": "TenantID"
}
}
],
"email_verified": true,
"clientID": "wxxxvC8",
"updated_at": "2015-07-15T16:26:30.526Z",
"user_id": "windowslive|f1axxxac",
"identities": [
{
"access_token": "EwBwAq1",
"provider": "windowslive",
"user_id": "f1aexxxxxac",
"connection": "windowslive",
"isSocial": true
}
],
"created_at": "2015-07-01T06:08:21.358Z"
}}
Type: 2
I need to check if the tenantID actually exists and then get value, else return null or 0.
You should be able to do:
JObject jObject = JObject.Parse(...);
JToken value = jObject.SelectToken("value");
You parse your object, then the inner contents should be exposed in which you can leverage the SelectToken method to find that specific value.
To build it out a bit, you could potentially do:
public static JToken FindToken<T>(string key, T value)
{
string serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
var jObject = JObject.Parse(serialized);
var jToken = jObject.SelectToken(key);
if(jToken != null)
return jToken;
return null;
}
I still cannot get the overall picture of your JSON, though have a look at this. It may help you.
var str = #"{
""x"": [{
""value"": 1,
""metadata"": {
""userType"": 0,
""flags"": 8,
""type"": {
""type"":""INT4"",
""name"":""Int"",
""id"": 56
},
""colName"":""TenantID""
}
}
]
}";
var parentJObject = JObject.Parse(str);
var xJArray = (JArray)parentJObject["x"];
// first item in JArray which is the object of interest
// look for the appropriate index of the JObject of your data
var firstJTokenInxJArray = (JObject)xJArray[0];
Console.WriteLine(firstJTokenInxJArray["value"].ToString());
I got what I was looking for :
JToken value;
if (usr.Profile.TryGetValue("tenantid", out value))
{
User.TenantID = (int)value [0] ["value"];
}

Find field with specific key in Json

In my c# project I use Json.net Library.
I have long Json with many subfields, for ex:
{
"count": 10,
"Foo1": [
{
"id": "1",
"name": "Name1"
},
{
"id": "2",
"name": "Name3"
},
{
"id": "3",
"name": "Name4"
}
],
"Foo2": [
{
"id": "4",
"name": "Name3",
"specific_field": "specific_values1"
},
{
"id": "5",
"name": "Name3",
"specific_field": "specific_values2"
},
{
"id": "6",
"name": "Name3",
"specific_field": "specific_values3"
}
],
"Foo3": [
{
"id": "7"
},
{
"id": "8"
},
{
"id": "9"
}
]
}
And I need to get List of all specific_field (id 4-6), but cant deserialized json to object, because Foo1, Foo2 ... changed dynamically.
I want to know, is this possible to get values of specific_field when i have only json?
I think, I found solution:
var list = new List<string>();
var result = ((JToken)json);
foreach (var res in result)
{
list.AddRange(from foo in res.First let ret = foo["specific_field"] where (dynamic) ret != null select foo["specific_field"].ToString());
}
In comment, provide, what do you think about it?
You could use dynamics:
string json = "your JSON string comes here";
dynamic deserializedValue = JsonConvert.DeserializeObject(json);
var values = deserializedValue["Foo2"];
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine(values[i]["specific_field"]);
}

Categories