Adding Bodyparameter to POST request (C# and RestSharp) - c#

I am quite new to programming and I am meant to make a post request to Taxdoo APi. I am using the latest version of RestSharp. I tried reading their documentation but the lack of example code has me, as a beginner, crying in a corner. Here's the problem:
The API expects an array of products with the following payload format:
{
"products": [
{
"description": "Couch Supreme red",
"productIdentifier": "redcouch123",
"commodityCode": "9394240000",
"purchasePrice": 3200,
"currency": "EUR"
},
{
"description": "Wood table",
"productIdentifier": "wt234bas",
"commodityCode": "9394220000",
"purchasePrice": 300,
"currency": "EUR"
}
]
}
How can I get the products : into the request?
I tried the request.AddParameter, the request.AddOrUpdateParameter, I tried letting RestSharp do the parsing with request.AddJsonBody but I am so lost. I get BadRequest Error every time.
My code so far:
namespace ConnectToApi
{
internal class Program
{
static void Main(string[] args)
{
var endpoint = new Uri("https://sandbox-api.taxdoo.com/products");
using (RestClient? restClient = new(endpoint))
{
var request = new RestRequest();
var authToken = ConfigurationManager.AppSettings["authToken"];
request.AddHeader("AuthToken", authToken);
MyProduct productOne = new MyProduct
{
Description = "Product 1",
ProductIdentifier = "GBP-120",
CommodityCode = "123456",
PurchasePrice = 40,
Currency = "USD"
};
MyProduct productTwo = new MyProduct
{
Description = "Product 2",
ProductIdentifier = "GBP-125",
CommodityCode = "789101112",
PurchasePrice = 20,
Currency = "USD"
};
List<MyProduct> productList = new();
productList.Add(productOne);
productList.Add(productTwo);
string json = JsonConvert.SerializeObject(productList,Formatting.Indented);
request.AddStringBody(json, DataFormat.Json);
var response = restClient.Execute(request);
}
}
}
The JSONString looks like so:
[
{
"description": "Product 1",
"productIdentifier": "GBP-120",
"commodityCode": "123456",
"purchasePrice": 40,
"currency": "USD"
},
{
"description": "Product 2",
"productIdentifier": "GBP-125",
"commodityCode": "789101112",
"purchasePrice": 20,
"currency": "USD"
}
]
If anyone could help or send me a ressource where to look that is beginner friendly, I would be really glad.
Cheers guys.

You don't need serialization, just a wrapping class:
public class Body
{
public List<MyProduct> Products { get; set; }
}
...
var body = new Body();
body.Products = productList;
request.AddStringBody(body, DataFormat.Json);

You need to add a product wraping around your list before serialization. And add Post to your request. You can use an anonymous class for example
var request = new RestRequest(endpoint, Method.POST);
....
var products = new { Products = productList};
string json = JsonConvert.SerializeObject(products);
request.AddStringBody(json, DataFormat.Json);
var response = restClient.Execute(request);

Related

how to work with nested json object in c#

api return json which is nested and i dont know to retrieve data from it and map it to my model. i want to retrieve the data from nested but not sure how to do this with index and value. Thanks in Advance.
public class MikesExcelModel
{
//public int id;
//public object AuthorizingManagerId;
public string Name;
//public DateTime UpdateDate;
public string Phone;
public string Email;
}
public class MikesExcelResults
{
public List<MikesExcelModel> value = new List<MikesExcelModel>();
}
public List<MikesExcelModel> GetExcel()
{
using (HttpClient client = new HttpClient())
{
addToken(client);
var result = client.GetAsync("https://graph.microsoft.com/beta/sites/ucfdev.sharepoint.com,4c319763-130d-4ee1-bc1f-72543da0a847,8a2f59f4-9d56-4aec-be21-33d0347293d1/drives/b!Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m/items/01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH/workbook/worksheets('sheet1')/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows").Result;
if (result.IsSuccessStatusCode)
{
var responseContent = result.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
JavaScriptSerializer serialiser = new JavaScriptSerializer();
// dynamic apiResult = serialiser.DeserializeObject(responseString);
return Utilities.DeserializeObject<MikesExcelResults>(result.Content.ReadAsStringAsync().Result).value;
}
else
throw new Exception("Couldn't get excel datas.");
}
}
}
Data return by api looks like this:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets('sheet1')/tables('%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D')/rows",
"value": [
{
"#odata.id": "/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=0)",
"index": 0,
"values": [
[
"Mike Callahan",
"407-266-1431",
"MTC#ucf.edu"
]
]
},
{
"#odata.id": "/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=1)",
"index": 1,
"values": [
[
"Michael Callahan",
"407-823-3455",
"mtcallah#ucf.edu"
]
]
},
{
"#odata.id": "/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=2)",
"index": 2,
"values": [
[
"cvcfcv",
"zVCCvc",
"cvvvvb"
]
]
}
]
}
Maybe traditional way to extract JSON data with Newtonsoft.Json library.
Convert jsonData to JObject (via JObject.Parse).
Get first-level value.
Get second-level values.
Flatten second-level values.
From
[[["Mike Callahan", "407-266-1431", "MTC#ucf.edu"], ...]]
To
[["Mike Callahan", "407-266-1431", "MTC#ucf.edu"], ...]
Convert flattenChildrenValues to List<MikesExcelModel>.
Add List<MikesExcelModel> to results.value
using System;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
var jsonData = #"{
""#odata.context"": ""https://graph.microsoft.com/beta/$metadata#sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets('sheet1')/tables('%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D')/rows"",
""value"": [
{
""#odata.id"": ""/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=0)"",
""index"": 0,
""values"": [
[
""Mike Callahan"",
""407-266-1431"",
""MTC#ucf.edu""
]
]
},
{
""#odata.id"": ""/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=1)"",
""index"": 1,
""values"": [
[
""Michael Callahan"",
""407-823-3455"",
""mtcallah#ucf.edu""
]
]
},
{
""#odata.id"": ""/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=2)"",
""index"": 2,
""values"": [
[
""cvcfcv"",
""zVCCvc"",
""cvvvvb""
]
]
}
]
}";
var jsonObj = JObject.Parse(jsonData);
// Get first-level value
JArray jsonValue = jsonObj["value"] as JArray;
// Get second-level values
var childrenValues = jsonValue.Children<JObject>()["values"];
// Flatten second-level values
var flattenChildrenValues = childrenValues.Values<JArray>() as IEnumerable<JArray>;
// Read flattenChildrenValues to List<MikesExcelModel>
List<MikesExcelModel> excelModels = flattenChildrenValues
.Select(x => new MikesExcelModel
{
Name = x[0].ToString(),
Phone = x[1].ToString(),
Email = x[2].ToString()
})
.ToList();
// Add List<MikesExcelModel> to results.value
MikesExcelResults results = new MikesExcelResults();
results.value.AddRange(excelModels);
foreach (var model in results.value)
{
Console.WriteLine(String.Format("Name: {0}, Phone: {1}, Email: {2}", model.Name, model.Phone, model.Email));
}
Sample program

how to replace property values in a dynamic JSON?

I'm reading my json file from and trying to replace the property values. JSON file is below.
{
"fields": {
"summary": "summaryValue",
"project": {
"key": "projectValue"
},
"priority": {
"name": "priorityValue"
},
"Requestor": {
"name": "RequestorValue"
},
"issue": {
"name": "issueValue"
},
"labels": "LabelValue",
"customfield_xyz": "customfield_xyzValue"
}
}
How can I replace the value for each item inside the fields property ?
for ex:
{"fields": {
"summary": "NewsummaryValue",
"project": {
"key": "NewprojectValue"
},
"priority": {
"name": "NewpriorityValue"
}
}
}
Below is the code to parse my json file,
StreamReader r = new StreamReader(filepath);
var jsondata = r.ReadToEnd();
var jobj = JObject.Parse(jsondata);
foreach (var item in jobj.Properties())
{
\\replace code
}
I do not know exactly what you want. But I changed the json information in the code snippet as you wanted.
dynamic dataCollection = JsonConvert.DeserializeObject<dynamic>(jsonData);
string summary = dataCollection["fields"]["summary"];
string project = dataCollection["fields"]["project"]["key"];
string priority = dataCollection["fields"]["priority"]["name"];
dynamic json = new JObject();
json.summary = summary;
json.project = project;
json.priority = priority;
dynamic jsonRoot = new JObject();
jsonRoot.fields = json;
Console.WriteLine(jsonRoot.ToString());
output:

How can I retrieve and capture Adaptive card result from drop down box or Check list

I have created a LUIS Template Bot Application (Version 3) and I need to capture the output of an Adaptive Card drop down list. I am currently able to create and render the drop down list but facing difficulty capturing the result once the button is clicked. Can you please give me a solution or give link to appropriate tutorial for version 3 as resources for this issue is mostly for version 4.
public Attachment PolicyAdaptiveCard()
{
var card = new AdaptiveCard();
var choices = new List<AdaptiveChoice>();
choices.Add(new AdaptiveChoice()
{
Title = "Category 1",
Value = "c1"
});
choices.Add(new AdaptiveChoice()
{
Title = "Category 2",
Value = "c2"
});
var choiceSet = new AdaptiveChoiceSetInput()
{
IsMultiSelect = false,
Choices = choices,
Style = AdaptiveChoiceInputStyle.Compact,
Id = "Category"
};
card.Body.Add(choiceSet);
card.Actions.Add(new AdaptiveSubmitAction() { Title = "Select Category", Data = Newtonsoft.Json.Linq.JObject.FromObject(new { button = "select" }) });
Attachment attachment = new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = card,
Name = $"Card"
};
return attachment;
}
This is JSON output that I am capturing in Bot Emmulator
{
"channelData": {
"clientActivityID": "15547009411880.yfus2yy2mao",
"postBack": true
},
"channelId": "emulator",
"conversation": {
"id": "3f50f7c1-59be-11e9-98bd-17dcaa70e8d3|livechat"
},
"from": {
"id": "r_tckd4zoa8h",
"name": "User",
"role": "user"
},
"id": "48d27080-59be-11e9-93ff-a77a4eb2d000",
"localTimestamp": "2019-04-08T08:22:21+03:00",
"locale": "en-US",
"recipient": {
"id": "97e06f60-496a-11e9-9541-3d37a55e03cc",
"name": "Bot",
"role": "bot"
},
"serviceUrl": "http://localhost:56373",
"showInInspector": true,
"timestamp": "2019-04-08T05:22:21.192Z",
"type": "message",
"value": {
"Category": "c1",
"button": "select"
}
}
How can I read the value and output "c1" in the next method ? This is the code that I am following. Can you please give me the method I can use to capture the category value
var reply = context.MakeMessage();
var activityValue = context.Activity.AsMessageActivity().Value as Newtonsoft.Json.Linq.JObject;
if (activityValue != null)
{
var categorySelection = activityValue.ToObject<CategorySelection>();
var category = categorySelection.Category;
await context.PostAsync(reply);
}
For bot framework v3 you could do something like this as your callback function:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
if (activity.Value != null)
{
dynamic value = activity.Value;
var category = value.Category;
await context.PostAsync(category);
}
context.Wait(MessageReceivedAsync);
}
Using dynamics it's very easy to access the values. Simply register this message as callback function on context.Wait in your initial prompt where you send your adaptive card.
If you would like to have a more typed version, you could model the result of you card and parse it like this:
private static string GetTypedCategoryFromAdaptiveCard(Activity activity)
{
var content = JsonConvert.DeserializeObject<CategoryResponse>(activity.Value.ToString());
return content.Category;
}
public class CategoryResponse
{
public string Category { get; set; }
}

Converting JSON code of Facebook's Generic Template to C# in Bot framework

I am having a hard time converting this generic template of facebook to C#. I am not sure if i converted it right. Below is the code i tried but is not rendering on messenger. Thank you.
curl -X POST -H "Content-Type: application/json" -d '{
"recipient":{
"id":"<PSID>"
},
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements":[
{
"title":"Welcome!",
"image_url":"https://petersfancybrownhats.com/company_image.png",
"subtitle":"We have the right hat for everyone.",
"default_action": {
"type": "web_url",
"url": "https://petersfancybrownhats.com/view?item=103",
"webview_height_ratio": "tall",
},
"buttons":[
{
"type":"web_url",
"url":"https://petersfancybrownhats.com",
"title":"View Website"
},{
"type":"postback",
"title":"Start Chatting",
"payload":"DEVELOPER_DEFINED_PAYLOAD"
}
]
}
]
}
}
}
}' "https://graph.facebook.com/v2.6/me/messages?access_token=<PAGE_ACCESS_TOKEN>"
This is what i tried in c# but it is not working. I am not sure if i converted it the proper way. Any help would be appreciated thank you.
Activity previewReply = stepContext.Context.Activity.CreateReply();
previewReply.ChannelData = JObject.FromObject(
new
{
attachment = new
{
type = "template",
payload = new
{
template_type = "generic",
elements = new
{
title = "title",
subtitle = "subtitle",
image_url = "https://thechangreport.com/img/lightning.png",
buttons = new object[]
{
new
{
type = "element_share,",
share_contents = new
{
attachment = new
{
type = "template",
payload = new
{
template_type = "generic",
elements = new
{
title = "x",
subtitle = "xx",
image_url = "https://thechangreport.com/img/lightning.png",
default_action = new
{
type = "web_url",
url = "http://m.me/petershats?ref=invited_by_24601",
},
buttons = new
{
type = "web_url",
url = "http://m.me/petershats?ref=invited_by_24601",
title = "Take Quiz",
},
},
},
},
},
},
},
},
},
},
});
await stepContext.Context.SendActivityAsync(previewReply);
The elements and buttons attributes need to be lists. Take a look at the example template below.
var attachment = new
{
type = "template",
payload = new
{
template_type = "generic",
elements = new []
{
new {
title = "title",
image_url = "https://thechangreport.com/img/lightning.png",
subtitle = "subtitle",
buttons = new object[]
{
new {
type = "element_share",
share_contents = new {
attachment = new {
type = "template",
payload = new
{
template_type = "generic",
elements = new []
{
new {
title = "title 2",
image_url = "https://thechangreport.com/img/lightning.png",
subtitle = "subtitle 2",
buttons = new object[]
{
new {
type = "web_url",
url = "http://m.me/petershats?ref=invited_by_24601",
title = "Take Quiz"
},
},
},
},
},
}
},
},
},
},
},
},
};
reply.ChannelData = JObject.FromObject(new { attachment });
Note, you only need to add a share_contents element to your template if your main template is different from the template you are trying to share. Otherwise, your button can just be new { type = "element_share" }, which makes the template far less complex.
Also, be sure to Whitelist all of your URLs and make sure all of the image URLs work properly - a couple of them weren't working properly. The template won't render if the URLs aren't Whitelisted and image links are broken.
Hope this helps!

C# MongoDb - Output id field properly?

I don't understand how can I output id properly when displaying objects. It's either ObjectId() that I can't parse back to object or some object that has id in it that I can parse but it looks weird.
Note that mapping it to class is not an option, it needs to be fully dynamic because different users have different fields.
Code
public List<object> Get()
{
var client = new MongoClient("mongodb://localhost");
var server = client.GetServer();
var database = server.GetDatabase("api_test");
var collection = database.GetCollection("users");
var json = collection.FindAllAs<BsonDocument>().ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.Strict });
var obj = JsonConvert.DeserializeObject<List<object>>(json);
return obj;
}
Example
[
{
"_id": {
"$oid": "528e7f9bb1fece903aa9b246"
},
"Name": "Steve",
"Age": 60
},
{
"_id": {
"$oid": "528e7fabb1fece903aa9b247"
},
"Name": "Alice",
"Age": 44
}
]
What I would like
[
{
"_id": "528e7f9bb1fece903aa9b246",
"Name": "Steve",
"Age": 60
},
{
"_id": "528e7fabb1fece903aa9b247",
"Name": "Alice",
"Age": 44
}
]
You can do this by explicitly updating your query result to convert _id to a string before it's serialized to JSON:
var docs = test.FindAll().ToList();
foreach (var doc in docs)
{
doc["_id"] = doc["_id"].ToString();
}
var json = docs.ToJson(
new JsonWriterSettings { OutputMode = JsonOutputMode.Strict });

Categories