Create dynamic object from a JSON disregarding null fields - c#

I need to consume a method that the input parameter is a dynamic object, but I feed the object through a received JSON
Dynamic Builder:
public static dynamic PayChargeObject()
{
var body = new
{
payment = new
{
banking_billet = new
{
customer = new
{
name = "",
email = "",
cpf = "",
birth = "",
phone_number = "",
address = new
{
street = "",
number = "",
neighborhood = "",
zipcode = "",
city = "",
complement = "",
state = "",
},
juridical_person = new
{
corporate_name = "",
cnpj = "",
}
},
expire_at = "",
discount = new
{
type = "",
value = 0
},
conditional_discount = new
{
type = "",
value = 0,
until_date = ""
},
message = ""
}
}
};
return body;
}
My JSON Data:
{
"payment": {
"banking_billet": {
"customer": {
"name": "person name",
"email": "personnamez#gerencianet.com.br",
"cpf": "94271564656",
"birth": "1977-01-15",
"phone_number": "41991234567"
},
"expire_at": "2019-12-12"
}
}
Note that json will not always have all available fields in the object filled, but the method I need to consume does not accept null values in the fields, and my problem is this, when deserializing JSON in the dynamic object, the fields not used in JSON are created as null in the dynamic object
JSON Convert and Method call:
var obj = JsonConvert.DeserializeAnonymousType(MyJSON, PayChargeObject())
dynamicMethod.PayCharge(obj);
Dynamic Object with null fields on Debug
How can I solve this problem?

With help of #dbc solution:
replace:
var obj = JsonConvert.DeserializeAnonymousType(MyJSON, PayChargeObject())
dynamicMethod.PayCharge(obj);
with:
dynamicMethod.PayCharge(JObject.Parse(MyJSON));

Related

403 Error using PostAsJsonAsync but Works in Postman

I'm trying to create a POST call using HttpClient that I have fully working in Postman. Here is the body I'm sending in Postman:
{
"searchType": "games",
"searchTerms": [
"mario"
],
"searchPage": 1,
"size": 20,
"searchOptions": {
"games": {
"userId": 0,
"platform": "",
"sortCategory": "popular",
"rangeCategory": "main",
"rangeTime": {
"min": 0,
"max": 0
},
"gameplay": {
"perspective": "",
"flow": "",
"genre": ""
},
"modifier": ""
},
"users": {
"sortCategory": "postcount"
},
"filter": "",
"sort": 0,
"randomizer": 0
}
}
I have this written as the following in C#:
var client = _httpClientFactory.CreateClient(HttpClients.HowLongToBeat.ToString());
var request = new HowLongToBeatRequest
{
SearchType = "games",
SearchTerms = searchTerm.Trim().Split(" "),
SearchPage = 1,
Size = 20,
SearchOptions = new SearchOptions
{
Games = new SearchOptionsGames
{
UserId = 0,
Platform = "",
SortCategory = "popular",
RangeCategory = "main",
RangeTime = new SearchOptionsGamesRangeTime
{
Min = 0,
Max = 0
},
Gameplay = new SearchOptionsGamesGameplay
{
Perspective = "",
Flow = "",
Genre = ""
},
Modifier = ""
},
Users = new SearchOptionsUsers
{
SortCategory = "postcount"
},
Filter = "",
Sort = 0,
Randomizer = 0
}
};
//var json = JsonSerializer.Serialize(request);
//var content = new StringContent(json, Encoding.UTF8, "application/json");
//var response = await client.PostAsync("api/search", content);
var response = await client.PostAsJsonAsync("api/search", request, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
return new HowLongToBeatResponse();
I have this set up as
The url I'm hitting is: https://www.howlongtobeat.com/api/search and I'm setting it up like so in my Startup.cs
services.AddHttpClient(HttpClients.HowLongToBeat.ToString(), config =>
{
config.BaseAddress = new Uri("https://www.howlongtobeat.com/");
config.DefaultRequestHeaders.Add("Referer", "https://www.howlongtobeat.com/");
});
I am passing this Referer header in my Postman collection as well.
Basically, I can't figure out why this code gets a 403 in C# but the Postman that I think is exactly the same is getting a successful response. Am I missing something?
Let me know if there's any missing info I can provide.
I solved my problem. The issue was that this specific API required a User Agent header specified.
I think the problem is here, The BaseAddress property needs to be suffixed (https://www.howlongtobeat.com/) with a forward slash and here you already set route as well, change it to
services.AddHttpClient(HttpClients.HowLongToBeat.ToString(), config =>
{
config.BaseAddress = new Uri("https://www.howlongtobeat.com/");
config.DefaultRequestHeaders.Add("Referer", "https://www.howlongtobeat.com/api/search");
});
And then
var response = await client.PostAsJsonAsync("api/search", request, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
Updated:
try this, here I have hard-coded the Base URL for testing purposes.
try
{
var data_ = JsonConvert.SerializeObject(root);
var buffer_ = System.Text.Encoding.UTF8.GetBytes(data_);
var byteContent_ = new ByteArrayContent(buffer_);
byteContent_.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string _urls = "https://www.howlongtobeat.com/api/search";
var responses_ = await _httpClient.PostAsJsonAsync(_urls, byteContent_);
if (responses_.StatusCode == HttpStatusCode.OK)
{
Console.WriteLine("[GetPrimeryAccount] Response: Success");
string body = await responses_.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); ;
}

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!

XML-mapping to SQL-server

I want to map a xml file to a SQL Server table.
This is what I've done so far:
XmlTextReader reader = new XmlTextReader("navetout.xml");
XmlNodeType type;
while (reader.Read())
{
type = reader.NodeType;
if(type == XmlNodeType.Element)
{
}
}
//using Entity framework
static void writeToDatabase()
{
BumsEntities _bums = new BumsEntities();
_bums.Seamen.Add(new Seamen
{
PersonalIdentityNumber = "",
ReferedCivicRegistrationNumber = "",
UnregistrationReason = "",
UnregistrationDate = "",
MessageComputerComputer = "",
GivenNameNumber = "",
FirstName = "",
MiddleName = "",
LastName = "",
NotifyName = "",
NationalRegistrationDate = "",
NationalRegistrationCountyCode = "",
NationalRegistrationMunicipalityCode = "",
NationalRegistrationCoAddress = "",
NationalRegistrationDistributionAddress1 = "",
NationalRegistrationDistributionAddress2 = "",
NationalRegistrationPostCode = "",
NationalRegistrationCity = "",
NationalRegistrationNotifyDistributionAddress = "",
NationalRegistrationNotifyPostCode = "",
NationalRegistrationNotifyCity = "",
ForeignDistrubtionAddress1 = "",
ForeignDistrubtionAddress2 = "",
ForeignDistrubtionAddress3 = "",
ForeignDistrubtionCountry = "",
ForeignDate = "",
BirthCountyCode = "",
BirthParish = "",
});
_bums.SaveChanges();
}
The code above is the database columns. What I want to be able to do is to load the xml file and insert the tags into the columns. The problem is that I don't know how to "translate" the xml tags to the database columns.. Can anyone help me out?
This is not the entire code, however should help :
XmlTextReader reader = new XmlTextReader("navetout.xml");
DataSet ds = new DataSet("XML Data");
ds.ReadXml(reader);
// Create Database Connection here
foreach(DataTable dt in ds.Tables){
//save datatable to database - You can use SqlBulkCopy
}
Saving DataTable to database

Initialize array with a mix of with hard-coded and generated values

This code which initializes an array with two hard-coded values is working perfectly fine:
var db = new GoogleGraph {
cols = new ColInfo[] {
new ColInfo { id = "", label = "Date", pattern ="", type = "string" },
new ColInfo { id = "", label = "Attendees", pattern ="", type = "number" }
}.ToList(),
rows = new List<DataPointSet>()
};
db.cols.AddRange(listOfValues.Select(p => new ColInfo { id = "", label = p, type = "number" }));
This code which attempts to add some dynamically generated values is not working:
var db = new GoogleGraph {
cols = new ColInfo[] {
new ColInfo { id = "", label = "Date", pattern ="", type = "string" },
new ColInfo { id = "", label = "Attendees", pattern ="", type = "number" },
listOfValues.Select(p => new ColInfo { id = "", label = p, type = "number" })
}.ToList(),
rows = new List<DataPointSet>()
};
How can I correctly implement the above snippet?
You can't pass an IEnumerable<T> to an initializer of T[] like that.
You can do what you want by putting the hard-coded objects in their own collection, then concatenating the dynamic ones:
var db = new GoogleGraph {
cols =
new ColInfo[] {
new ColInfo { id = "", label = "Date", pattern ="", type = "string" },
new ColInfo { id = "", label = "Attendees", pattern ="", type = "number" }
}
.Concat(listOfValues.Select(p =>
new ColInfo { id = "", label = p, type = "number" }))
.ToList(),
rows = new List<DataPointSet>()
};

get Contacts based on Account in SugarCRM REST API in C# .Net

i want to retrieve all contacts based on account in sugarcrm rest api using C# .net
i have tried
json = serializer.Serialize(new
{
session = sessionId,
module_name = "accounts",
query = "",
order_by = "",
offset = "0",
select_fields = "",
link_name_to_fields_array = "",
max_results = "2000",
deleted = 0
});
values = new NameValueCollection();
values["method"] = "get_entry_list";
values["input_type"] = "json";
values["response_type"] = "json";
values["rest_data"] = json;
response = client.UploadValues(sugarUrl, values);
responseString = Encoding.Default.GetString(response);
var accountsList = serializer.Deserialize<Dictionary<string, dynamic>>(responseString);
i am able to get all accounts and contacts but i am not getting relations between them i.e which contact belong to which account
Thanks for help in advance
UPDATE :
object[] linkNameToFieldsArray = new object[1]
{
new object[2, 2]
{
{ "name", "contacts" },
{ "value", new string[2]
{ "id", "last_name"
}
}
};
json = serializer.Serialize(new
{
session = sessionId,
module_name = "accounts",
query = "",
order_by = "",
offset = "0",
select_fields = "",
link_name_to_fields_array = linkNameToFieldsArray , ***//just added this to get related records***
max_results = "2000",
deleted = 0
});
values = new NameValueCollection();
values["method"] = "get_entry_list";
values["input_type"] = "json";
values["response_type"] = "json";
values["rest_data"] = json;
response = client.UploadValues(sugarUrl, values);
responseString = Encoding.Default.GetString(response);
var accountsList = serializer.Deserialize<Dictionary<string, dynamic>>(responseString);
Assuming a SugarCRM 6.4 or 6.5 system and API version REST v4_1...
I don't know the C#/.NET syntax/lingo, but 'link_name_to_fields_array' needs to be an array with keys of module names (e.g. "Contacts") and values that are arrays of the fields you want. The JSON would look like this:
{
"session":"asdfasdfsrf9ebp7jrr71nrth5",
"module_name":"Accounts",
"query":"",
"order_by":null,
"offset":0,
"select_fields":[
"id",
"name"
],
"link_name_to_fields_array":[
{
"name":"contacts",
"value":[
"id",
"last_name"
]
}
],
"max_results":"2",
"deleted":false
}
Also - I wrote this to help non PHP-devs interact with this version of the API, since documention is largely PHP based. You may find it useful: https://gist.github.com/matthewpoer/b9366ca4197a521a600f

Categories