.NET 5.0 options pattern using JSON array - c#

I am building a C# .NET 5.0 application to talk to an external API for which we have multiple accounts that we can post data to. I am trying to store these details in appsettings.json file and use the options pattern to retrieve the settings.
I have the following structure in my app settings.json
"SomeApi": {
"Url": "https://api.someapi.net/v3/",
"Secret": "mysecretvlaue",
"ClientId": "myclientid",
"Accounts": [
{
"Name": "Bob",
"Username": "HisUsername",
"Password": "HisPassword",
"PostingLocation": "HisLocation"
},
{
"Name": "Fred",
"Username": "HisUsername",
"Password": "HisPassword",
"PostingLocation": "HisLocation"
}
]
},
I have a class set up like this:
public class SomeApiOptions
{
public const string SomeApi = "SomeApi";
public string Url { get; set; }
public string Secret { get; set; }
public string ClientId { get; set; }
public List<Account> Accounts { get; set; }
}
public class Account
{
string Name { get; set; }
string Username { get; set; }
string Password { get; set; }
string PostingLocation { get; set; }
}
My startup.cs has this:
services.Configure<SomeApiOptions>(Configuration.GetSection(SomeApiOptions.SomeApi));
Finally, I inject IOptions to the class where I need to use the settings like so:
Public MyClass (IOptionsSnapshot<SomeApiOptions> options)
The issue I am having is the Accounts never get populated with their respective values.
Url, Secret etc. are populated and the number of elements items in the Accounts list is correct, but all of the properties have null values.
I have looked at similar questions and tried restructuring my JSON a few ways but still end up with null values.
Any help greatly appreciated.

I see a couple of problems here.
First, none of the properties in the Account class are public so you need to change that:
Second, the Location property doesn't match the JSON which is PostingLocation. Your class should be:
public class Account
{
public string Name { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string PostingLocation { get; set; }
}

Related

The fields that are given to the settings appear in the subclasses when serializing the object

I have classes like this.
public class Activity
{
public Guid Id { get; set }
public string Name { get; set; }
public Firm RelatedFirm { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
}
public class Firm
{
public Guid Id { get; set }
public string Title { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
}
After capturing the activity list, I'm sending them to a function to serialize. Within this function, serialize operation is performed according to certain parameters. One of these parameters is the fields in which I want the response to return. I want to return the Id, Name, RelatedFirm, Email and Notes fields for the activity and I want only the Id field to return to the Firm. The fields that I want to return to within the activity turn to me if they are in the firm.
This is my response;
{
"Id": "9294bc10-d8e1-4590-9703-75b773110d1c",
"Email": "q#q.com",
"RelatedFirm": {
"Id": "ebbe560b-f75d-4daf-9500-89a10487e51f",
"Email": "x#x.com",
"Notes": "87654323ıuyt43"
},
"Notes": null
}
This is also the answer I want to come;
{
"Id": "9294bc10-d8e1-4590-9703-75b773110d1c",
"Email": "q#q.com",
"RelatedFirm": {
"Id": "ebbe560b-f75d-4daf-9500-89a10487e51f"
},
"Notes": null
}
Is there any way I can stop this?

Need a C# WebApi example of a Smartsheet callback controller method

I am working on a prototype for using Smartsheets webhooks to notify an ASP.Net/WebApi endpoint when changes occur. While I understand the concepts, I have not been able to find a specific example of the structure that Smartsheets will be passing to the callback endpoint.
I suspect that it is a Json string and that I should be able to define a string parameter in the controller method to accept it like this:
public HttpStatusCodeResult Put([FromBody]string payload)
{ ... }
but I am not clear on what the parameter should be named (or even if it matters what it is named).
Can someone provide:
An example of a Smartsheets webhook callback controller method
Clarification on what the payload parameter type and name should be
I finally figured this one out. I used the Json response structure to create a similar class in C#, then used that structure as the incoming parameter type:
public class Payload
{
public int PayloadId { get; set; }
public Guid Nonce { get; set; }
public string Timestamp { get; set; }
public string WebhookId { get; set; }
public string Scope { get; set; }
public string ScopeObjectId { get; set; }
public virtual List<PayloadEvent> Events { get; set; }
}
public class PayloadEvent
{
public int PayloadEventId { get; set; }
public string ObjectType { get; set; }
public string EventType { get; set; }
[JsonProperty(PropertyName = "Id")]
public string EventId { get; set; }
public string UserId { get; set; }
public string Timestamp { get; set; }
}
Controller code:
[HttpPost]
public void Post([FromBody] Payload value)
{
...
}
It is also possible to just use dynamic as the parameter type, but that doesn't take advantage of any compiler checks downstream so I opted for more structure by defining the classes.
I can help with the structure of the Webhook callback. Once you create and verify the webhook, the events will be posted to your callback endpoint in following format:
{
"nonce": "4b2ed20d-6f00-4b0c-8fac-082182aa9aac",
"timestamp": "2015-10-27T17:04:23.795+0000",
"webhookId": 4503604829677444,
"scope": "sheet",
"scopeObjectId": 4509506114742148,
"events": [
{
"objectType": "sheet",
"eventType": "updated",
"id": 4509506114742148,
"userId": 9007194052434043,
"timestamp": "2015-10-27T17:03:15.000+0000"
},
{
"objectType": "row",
"eventType": "created",
"id": 7129509179746180,
"userId": 9007194052434043,
"timestamp": "2015-10-27T17:03:15.000+0000"
}
]
}
The events array will be in the body of the POST.

JSON deserialize variable number of properties

I have a JSON class structure like this from a third party API (only the problem part shown):
"template": {
"name": "MovieTemplate",
"ruleName": "Movie Template",
"zones": {
"Products": {
"type": "Record",
"name": "Products",
"content": "www.imagescloudsite.com/blahblah.gif"
"records": [ … ]
},
"URL": {
"type":"DVD",
"name":"Bundle"
"content": "www.imagescloudsite.com/blahblah.gif"
}
}
}
The "zones" property can contain many properties "Products","URL","Superman","Descartes",etc...
But, I do not know which ones and how many will be there, because these are added by our content guys in a special control panel. Newtonsoft Deserializer complains because I have a model like this and it clearly does not capture the zone name like 'Products' and 'URL':
public class Zone
{
public string Type { get; set; }
public string Name { get; set; }
public string Content { get; set; }
}
public class Template
{
public string Name { get; set; }
public string RuleName { get; set; }
public List<Zone> Zones { get; set; }
}
Any ideas on how I can capture the zone names using NewtonSoft?
Thanks.
Turn your Zone property to a dictionary since you don't know the keys in before hand, but do know their content structure.
Like so
public class Template
{
public string Name { get; set; }
public string RuleName { get; set; }
public Dictionary<string,Zone> Zones { get; set; }
}
What if you changed the Template class to the following:
public class Template
{
public string Name { get; set; }
public string RuleName { get; set; }
public Dictionary<string, Zone> Zones { get; set; }
}
You could then access the name via the key of the entry.
Use of dynamic would be a good bet
dynamic d = Newtonsoft.Json.Linq.JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");

Deserialize JSON object structure with ids as keys [duplicate]

This question already has answers here:
How can I deserialize a child object with dynamic (numeric) key names?
(2 answers)
Closed 7 years ago.
I have this JSON that is generated by a third party web service
{
"user_data": {
"123456789": {
"transactions_id": 123456789,
"transaction_date": "2015-07-08T18:31:28+01:00",
"reason_type": "REWARD",
"category": "categoryFoo",
"title": "titleFoo",
"description": "",
"reward_quantity": 5,
"reward_name": " foo"
},
"1234567891": {
"transactions_id": 1234567891,
"transaction_date": "2015-07-08T18:33:06+01:00",
"reason_type": "REWARD",
"category": "categoryFoo",
"title": "titleFoo",
"description": "",
"reward_quantity": 5,
"reward_name": " foo"
},
"1234567892": {
"transactions_id": 1234567892,
"transaction_date": "2015-07-08T18:35:00+01:00",
"reason_type": "REWARD",
"category": "categoryFoo",
"title": "titleFoo",
"description": "",
"reward_quantity": 5,
"issuers_name": " foo"
}
}
}
The amount of transactions will change with each request so there may be 3 like this one time and then 10 the next. To handle the varying numbers of transactions I understand that you would need to use a list similar to this public List<User> users { get; set; } with users being similar to this
public class User
{
public int transactions_id { get; set; }
public string transaction_date { get; set; }
public string reason_type { get; set; }
public string category { get; set; }
public string title { get; set; }
public string description { get; set; }
public int reward_quantity { get; set; }
public string reward_name { get; set; }
}
However I do think this will work because of the weird structure of the JSON where each "transaction" has it ID as its name. Sorry I'm not sure of the correct terminology but I think you should be able to get the gist.
This isn't a particularly unusual structure in JSON. That should be deserialized to a Dictionary<string, User>:
public class Root
{
[JsonProperty("user_data")]
public Dictionary<string, User> Users { get; set; }
}
Then just use JsonConvert.DeserializeObject<Root> as normal.
Note how I'm using JsonProperty to specify how the name is represented in JSON while keeping idiomatic .NET property names - I suggest you do that in your User class too.
public class UserData
{
[JsonProperty("user_data")]
public Dictionary<string, User> Users { get; set; }
}

Json.NET Serializing my object gives me the wrong output

I'm having a bit of a problem with serializing my .NET objects into JSON using JSON.NET. The output I want to be serialized will have to look like this:
{"members":[
{"member":
{
"id":"4282",
"status":"1931",
"aktiv":"1",
"firmanavn":"firmname1",
"firmaUrl":"www.firmurl.dk",
"firmaUrlAlternativ":"",
"firmaSidstKontrolleretDato":"30-08-2010",
"firmaGodkendelsesDato":"07-03-2002"
}
},
{"member":
{
"id":"4283",
"status":"1931",
"aktiv":"1",
"firmanavn":"firmname2",
"firmaUrl":"www.firmurl.dk",
"firmaUrlAlternativ":"",
"firmaSidstKontrolleretDato":"30-08-2010",
"firmaGodkendelsesDato":"18-12-2000"
}
},
...... long list of members omitted
My .NET structure for now (still experimenting to get the right output) is like this:
public class Members
{
public List<Member> MemberList { get; set; }
}
and:
public class Member
{
[JsonProperty(PropertyName = "Id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "Status")]
public string Status { get; set; }
[JsonProperty(PropertyName = "Aktiv")]
public string Aktiv { get; set; }
[JsonProperty(PropertyName = "Firmanavn")]
public string Firmanavn { get; set; }
[JsonProperty(PropertyName = "FirmaUrl")]
public string FirmaUrl { get; set; }
[JsonProperty(PropertyName = "AltFirmaUrl")]
public string AlternativFirmaUrl { get; set; }
[JsonProperty(PropertyName = "FirmaSidstKontrolleretDato")]
public string FirmaSidstKontrolleretDato { get; set; }
[JsonProperty(PropertyName = "FirmaGodkendelsesDato")]
public string FirmaGodkendelsesDato { get; set; }
}
What the above .NET structure gives me when calling:
string json = JsonConvert.SerializeObject(members, Newtonsoft.Json.Formatting.Indented);
Where 'members' is a list of members. Is this:
{
"Members": [
{
"Id": "1062",
"Status": "1933",
"Aktiv": "1",
"Firmanavn": "firmname",
"FirmaUrl": "http://www.firmurl.dk",
"AltFirmaUrl": "http://www.altfirmurl.dk",
"FirmaSidstKontrolleretDato": "13-09-2011",
"FirmaGodkendelsesDato": "13-09-2511"
},
{
"Id": "1060",
"Status": "1933",
"Aktiv": "1",
"Firmanavn": "firmname2",
"FirmaUrl": "http://www.firmurl.dk",
"AltFirmaUrl": "http://www.altfirmurldk",
"FirmaSidstKontrolleretDato": "13-09-2011",
"FirmaGodkendelsesDato": "13-09-2511"
},
So basically, the structure is right in that it creates the array of members as expected, but I am missing the "member": label on each of the member objects. Is there any way to make such a label? Some kind of class declaration, or something?
I hope my question is clear, if not - please let me know and I'll try to explain further.
Thanks a lot in advance.
/ Bo
It sounds like you just need to make an intermediary object with a property of that name to get the JSON you want; however, I'd consider using the JSON.net originally rendered JSON (as it is structurally better).

Categories