I am trying to consume an Api for c# project.
I have the request body sample as follows:
{
"tx_ref":"hooli-tx-1920bbtytty",
"amount":"100",
"currency":"NGN",
"redirect_url":"https://webhook.site/9d0b00ba-9a69-44fa-a43d-a82c33c36fdc",
"payment_options":"card",
"meta":{
"consumer_id":23,
"consumer_mac":"92a3-912ba-1192a"
},
"customer":{
"email":"user#gmail.com",
"phonenumber":"080****4528",
"name":"Yemi Desola"
},
"customizations":{
"title":"Pied Piper Payments",
"description":"Middleout isn't free. Pay the price",
"logo":"https://assets.piedpiper.com/logo.png"
}
}
I want to convert the code to C#, I did it as below, but the "meta", "customer", "customizations" are nested in the request, when I tried to reproduce the nested part of the code to c# I get an error.
Please how do I place my C# code to reflect the body with the nested part of the code?
var keyValues = new Dictionary<string, string>
{
{ "tx_ref", "N-872653uy09-9"},
{ "amount", "500"},
{ "currency","NGN"},
{ "redirect_url","mysite.com/ConcludeFunding.aspx"},
{ "payment_options","card"},
{ "meta"," "},
{ "customer"("email",EmailV) },
{ "customizations","mysite.com/Assets/Logo.jpg"},
};
//serialization using Newtonsoft JSON
string JsonBody = JsonConvert.SerializeObject(keyValues);
For this type of situation, I would create a root class. Then I would assign value to the class object and finally I would serialize the object using Newtonsoft JSON.
Code:
using Newtonsoft.Json;
using System;
namespace Solve
{
internal class Program
{
public class Meta
{
public int consumer_id { get; set; }
public string consumer_mac { get; set; }
}
public class Customer
{
public string email { get; set; }
public string phonenumber { get; set; }
public string name { get; set; }
}
public class Customizations
{
public string title { get; set; }
public string description { get; set; }
public string logo { get; set; }
}
public class Root
{
public string tx_ref { get; set; }
public string amount { get; set; }
public string currency { get; set; }
public string redirect_url { get; set; }
public string payment_options { get; set; }
public Meta meta { get; set; }
public Customer customer { get; set; }
public Customizations customizations { get; set; }
}
static void Main(string[] args)
{
var rootObj = new Root()
{
tx_ref = "N-872653uy09-9",
amount = "500",
currency = "NGN",
redirect_url = "mysite.com/ConcludeFunding.aspx",
payment_options = "card",
meta = new Meta()
{
consumer_id = 23,
consumer_mac = "92a3-912ba-1192a"
},
customizations = new Customizations()
{
title = "Pied Piper Payments",
description = "Middleout isn't free. Pay the price",
logo = "https://assets.piedpiper.com/logo.png"
},
customer = new Customer()
{
email = "user#gmail.com",
phonenumber = "080****4528",
name = "Yemi Desola"
}
};
string json = JsonConvert.SerializeObject(rootObj);
Console.WriteLine(json);
}
}
}
Related
I need little help to create C# class to map below json response from FCM token info api (https://developers.google.com/instance-id/reference/server#get_information_about_app_instances):
{
"application": "com.chrome.windows",
"subtype": "wp:www.mydomain.com/#A1249A346-7458-45BB-A0F2-2AC4856BB-V2",
"scope": "*",
"authorizedEntity": "8212312155",
"rel": {
"topics": {
"topic1": {
"addDate": "2020-12-06"
}
}
},
"platform": "BROWSER"
}
Where topic1 is not the property name, rather a value and topics which is a property name contains the list of topics.
I am actually not sure how to represent the topics in above json.
It is Dictionary format.
public Dictionary<string, Topic> Topics {get;set;}
The class is like below:
public class Root
{
public string application { get; set; }
public string subtype { get; set; }
public string scope { get; set; }
public string authorizedEntity { get; set; }
public Rel rel { get; set; }
public string platform { get; set; }
}
public class Rel
{
public Dictionary<string, Topic> topics { get; set; }
}
public class Topic
{
public string addDate { get; set; }
}
The above json can be serialized from the below model:
var root = new Root
{
application = "com.chrome.windows",
subtype = "wp:www.mydomain.com/#A1249A346-7458-45BB-A0F2-2AC4856BB-V2",
scope = "*",
authorizedEntity = "8212312155",
rel = new Rel
{
topics = new Dictionary<string, Topic>
{
{
"topic1",
new Topic
{
addDate = "2020-12-06"
}
}
}
},
platform = "BROWSER"
};
public class Topic1 {
public string addDate { get; set; }
}
public class Topics {
public Topic1 topic1 { get; set; }
}
public class Rel {
public Topics topics { get; set; }
}
public class Root {
public string application { get; set; }
public string subtype { get; set; }
public string scope { get; set; }
public string authorizedEntity { get; set; }
public Rel rel { get; set; }
public string platform { get; set; }
}
https://json2csharp.com/
If you are sure that topics contain unique topic names , so use Dictionary, if not sure, then List
I have below json which I would like to read it in a list. below are the classes and model defined and the code by which I am trying to read. I am getting null value on binding. I am not sure how should i achieve this. So for example if I have multiple rules, I would like to read each one based on the condition passed. Please see my last sample code for better understanding.
Sample Json:
{"TableStorageRule": { "Rules": [ {
"Name": "filterRule1",
"DataFilter":
{
"DataSetType": "Settings1"
},
"TableSettings":
{
"AzureTable": {
"Account": "account1",
"Table": "table1",
"Key": "key1"
},
"SchemaBaseUri": "https://test.web.core.windows.net/"
}
},
{
"Name": "filterRule2",
"DataFilter":
{
"DataSetType": "Settings2"
},
"TableSettings":
{
"AzureTable": {
"Account": "account2",
"Table": "table2",
"Key": "key2"
},
"SchemaBaseUri": "https://test2.web.core.windows.net/"
}
}
] }}
Model and Code:
public class TableStoreSettings
{
public class AzureTableSettings
{
public string Account { get; set; }
public string Key { get; set; }
public string Table { get; set; }
}
public AzureTableSettings AzureTable { get; set; }
public Uri SchemaBaseUri { get; set; }
}
public class TableStorageRule
{
public string Name { get; set; }
public TwisterDataFilter DataFilter { get; set; }
public TableStoreSettings TableSettings { get; set; }
}
public class TableStorageConfiguration
{
public IEnumerable<TableStorageRule> Rules { get; set; } = new List<TableStorageRule>();
}
code by which I am trying to read:
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Root))
.AddJsonFile("appsettings.json", optional: false);
var config = builder.Build();
var tableStorageOutput = new TableStorageRule();
config.GetSection("TableStorageRule").Bind(tableStorageOutput);
var nameOfFilter = tableStorageOutput.Name;
if (tableStorageOutput.Name == "filterRule1")
{
var accountname = tableStorageOutput.TableSettings.AzureTable.Account;
}
on above I only get first filtername1 , i dont get other filternames and so on...though on GetSection() i see all the values in quick watch.
this is correct models from your JSON file :
public class DataFilter {
public string DataSetType { get; set; }
}
public class AzureTable {
public string Account { get; set; }
public string Table { get; set; }
public string Key { get; set; }
}
public class TableSettings {
public AzureTable AzureTable { get; set; }
public string SchemaBaseUri { get; set; }
}
public class Rule {
public string Name { get; set; }
public DataFilter DataFilter { get; set; }
public TableSettings TableSettings { get; set; }
}
public class TableStorageRule {
public List<Rule> Rules { get; set; }
}
public class Root {
public TableStorageRule TableStorageRule { get; set; }
}
for test you can read your JSON file and get values (maybe change models solve your problem in your code):
string json = File.ReadAllText(jsonFilePath);
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(json);
I want to assign value in List. i am not able to understand how can i assign value in List under Stops node. Can you please tell me how can i do this.Below is the code with class file
Created class from XML
[XmlRoot(ElementName="Customer")]
public class Customer {
[XmlAttribute(AttributeName="CustomerID")]
public string CustomerID { get; set; }
[XmlAttribute(AttributeName="CustomerCode")]
public string CustomerCode { get; set; }
[XmlAttribute(AttributeName="Name")]
public string Name { get; set; }
[XmlAttribute(AttributeName="Address")]
public string Address { get; set; }
}
[XmlRoot(ElementName="OrderStopPiece")]
public class OrderStopPiece {
[XmlAttribute(AttributeName="Sequence")]
public string Sequence { get; set; }
[XmlAttribute(AttributeName="PieceAction")]
public string PieceAction { get; set; }
}
[XmlRoot(ElementName="OrderStopPieces")]
public class OrderStopPieces {
[XmlElement(ElementName="OrderStopPiece")]
public OrderStopPiece OrderStopPiece { get; set; }
}
[XmlRoot(ElementName="Stop")]
public class Stop {
[XmlElement(ElementName="OrderStopPieces")]
public OrderStopPieces OrderStopPieces { get; set; }
[XmlAttribute(AttributeName="Sequence")]
public string Sequence { get; set; }
[XmlAttribute(AttributeName="StopType")]
public string StopType { get; set; }
[XmlAttribute(AttributeName="Note")]
public string Note { get; set; }
[XmlAttribute(AttributeName="Name")]
public string Name { get; set; }
}
[XmlRoot(ElementName="Stops")]
public class Stops {
[XmlElement(ElementName="Stop")]
public List<Stop> Stop { get; set; }
}
[XmlRoot(ElementName="Order")]
public class Order {
[XmlElement(ElementName="Customer")]
public Customer Customer { get; set; }
[XmlElement(ElementName="Stops")]
public Stops Stops { get; set; }
[XmlAttribute(AttributeName="UserID")]
public string UserID { get; set; }
[XmlAttribute(AttributeName="Notes")]
public string Notes { get; set; }
[XmlAttribute(AttributeName="CustomerID")]
public string CustomerID { get; set; }
}
[XmlRoot(ElementName="SaveOrder", Namespace="http://www.uBB.com/schemas/")]
public class SaveOrder {
[XmlElement(ElementName="Order")]
public Order Order { get; set; }
}
[XmlRoot(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public class Body {
[XmlElement(ElementName="SaveOrder", Namespace="http://www.uBB.com/schemas/")]
public SaveOrder SaveOrder { get; set; }
[XmlAttribute(AttributeName="UserGUID")]
public string UserGUID { get; set; }
}
[XmlRoot(ElementName="Envelope", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope {
[XmlElement(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
[XmlAttribute(AttributeName="m", Namespace="http://www.w3.org/2000/xmlns/")]
public string M { get; set; }
[XmlAttribute(AttributeName="SOAP", Namespace="http://www.w3.org/2000/xmlns/")]
public string SOAP { get; set; }
}
Code where i am assiging other values
var SaveOrder = new ECSaveOrderRequest.Envelope
{
Body = new ECSaveOrderRequest.Body
{
UserGUID = guid,
SaveOrder = new ECSaveOrderRequest.SaveOrder
{
Order = new ECSaveOrderRequest.Order
{
UserID = Uid,
Notes = "",
CustomerID = "",
Customer = new ECSaveOrderRequest.Customer
{
CustomerID = "",
CustomerCode = "",
Name = "",
Address = "",
City = ""
},
Stops = new ECSaveOrderRequest.Stops()
{
Stop = new List<ECSaveOrderRequest.Stop>()
{
/* Here i want to Assign value in List<stop> */
},
},
Jobs = new ECSaveOrderRequest.Jobs()
{
Job = new ECSaveOrderRequest.Job()
{
Sequence=""
}
}
},
}
}
};
[XmlRoot(ElementName="Stops")]
public class Stops {
[XmlElement(ElementName="Stop")]
public List<Stop> Stop { get; set; }
}
You can define a list and populate it outside of the code where you assign values.
When the list has all the values you want it to have, then you can assign the list to the property.
Stops = new ECSaveOrderRequest.Stops()
{
Stop = listWithStopValuesYouAssignedOutsideOfThisCodeBlock
}
Or another way of doing is by adding a new stop to the list like
Stop = new List<ECSaveOrderRequest.Stop>()
{
new ECSaveOrderRequest.Stop() {},
new ECSaveOrderRequest.Stop() {},
},
You can do the following.
Stops = new ECSaveOrderRequest.Stops()
{
Stop = new List<ECSaveOrderRequest.Stop>
{
new ECSaveOrderRequest.Stop {
Sequence = "",
StopType = ""
// rest of properties
},
new ECSaveOrderRequest.Stop {
Sequence = "",
StopType = ""
// rest of properties
},
}
},
But a better (more readable) solution would be create the List of Stop first and then assign it to Stops.Stop.
Stops = new ECSaveOrderRequest.Stops()
{
Stop = listOfStops
}
I am new to using the Json format with serializing and deserializing, I am using Json.Net.
As a little activity I decided to use the API from a game that I play to retrieve some simple statistics.
However, I am trying to put this Json into classes (created by json2csharp) but I get the exception.
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[TornCityAPI.PlayerStatistics.Stats+RootObject]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
and here is the code.
using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Windows.Forms;
namespace TornCityAPI
{
public partial class Form_Main : Form
{
// to hold the users api key
private string apiKey;
public string APIKey
{
get { return apiKey; }
set { apiKey = value; }
}
// location in the registry
private string registryLocation = #"HKEY_CURRENT_USER\TornCityAPI\Watch_App";
public string RegistryLocation
{
get { return registryLocation; }
}
// the url which will be used to retrive information
private string apiUrl = "https://api.torn.com/user/?selections=&key=";
public string ApiUrl
{
get { return apiUrl; }
set { apiUrl = value; }
}
// in case of a network disconnect, we could server the previous results instead.
private string previousTornStats;
public string PreviousTronStats
{
get { return previousTornStats; }
set { previousTornStats = value; }
}
public Form_Main()
{
InitializeComponent();
}
private void Form_Main_Load(object sender, EventArgs e)
{
CheckNetworkConnection();
// if the api key does not exists within the registry
if (Registry.GetValue(registryLocation, "Watch_App", null) == null)
{
// ask the user to insert theirs and open the form to allow that
MessageBox.Show("Please enter your torn API key!");
Form_APIKey apiWindow = new Form_APIKey();
apiWindow.ShowDialog(this);
}
// otherwise
else
{
// connect the url with the api key to get the full, working url to get the information
APIKey = (string)Registry.GetValue(registryLocation, "Watch_App", null);
ApiUrl += APIKey;
MessageBox.Show(apiUrl);
}
}
private void timer_UpdateStats_Tick(object sender, EventArgs e)
{
CheckNetworkConnection();
UpdateTornStats();
}
void UpdateTornStats()
{
using (var webClient = new WebClient())
{
var json = new WebClient().DownloadString(ApiUrl);
var list = JsonConvert.DeserializeObject<List<PlayerStatistics.Stats.RootObject>>(json);
Console.WriteLine(list.Count);
}
}
void CheckNetworkConnection()
{
// if they are not connected to the internet
if (NetworkInterface.GetIsNetworkAvailable() == false)
{
Console.WriteLine("You are not connected to the internet!" + "\n" + "Please connect and restart!");
return;
}
}
}
}
Specifically:
void UpdateTornStats()
{
using (var webClient = new WebClient())
{
var json = new WebClient().DownloadString(ApiUrl);
var list = JsonConvert.DeserializeObject<List<PlayerStatistics.Stats.RootObject>>(json);
Console.WriteLine(list.Count);
}
}
Here is the class I try to put it into.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TornCityAPI.PlayerStatistics
{
class Stats
{
public class Life
{
public int current { get; set; }
public int maximum { get; set; }
public int increment { get; set; }
public int interval { get; set; }
public int ticktime { get; set; }
public int fulltime { get; set; }
}
public class Job
{
public string position { get; set; }
public int company_id { get; set; }
public string company_name { get; set; }
}
public class Faction
{
public string position { get; set; }
public int faction_id { get; set; }
public int days_in_faction { get; set; }
public string faction_name { get; set; }
}
public class Married
{
public int spouse_id { get; set; }
public string spouse_name { get; set; }
public int duration { get; set; }
}
public class Icons
{
public string icon6 { get; set; }
public string icon3 { get; set; }
public string icon8 { get; set; }
public string icon27 { get; set; }
public string icon9 { get; set; }
}
public class RootObject
{
public string rank { get; set; }
public int level { get; set; }
public string gender { get; set; }
public string property { get; set; }
public string signup { get; set; }
public int awards { get; set; }
public int friends { get; set; }
public int enemies { get; set; }
public int forum_posts { get; set; }
public int karma { get; set; }
public int age { get; set; }
public string role { get; set; }
public int donator { get; set; }
public int player_id { get; set; }
public string name { get; set; }
public int property_id { get; set; }
public string last_action { get; set; }
public Life life { get; set; }
public List<string> status { get; set; }
public Job job { get; set; }
public Faction faction { get; set; }
public Married married { get; set; }
public Icons icons { get; set; }
}
}
}
I dont really know how to lay this out or what class should be created from the Json. (However I assume its the root as it has references to the other classes)
Finally, here is the Json which is downloaded to a string:
{
"rank": "Reasonable Punchbag",
"level": 22,
"gender": "Male",
"property": "Ranch",
"signup": "2013-08-01 07:59:43",
"awards": 58,
"friends": 2,
"enemies": 2,
"forum_posts": 25,
"karma": 4,
"age": 1234,
"role": "Civilian",
"donator": 1,
"player_id": 1761543,
"name": "GamingAnonymous",
"property_id": 16693,
"last_action": "18 minutes ago",
"life": {
"current": 429,
"maximum": 1072,
"increment": 53,
"interval": 300,
"ticktime": 258,
"fulltime": 3858
},
"status": [
"In hospital for 3 hrs 4 mins - Hospitalized by someone",
""
],
"job": {
"position": "Employee",
"company_id": 61582,
"company_name": "streamTV - hiring 33k man"
},
"faction": {
"position": "Member",
"faction_id": 17845,
"days_in_faction": 268,
"faction_name": "The Watchers"
},
"married": {
"spouse_id": 2024099,
"spouse_name": "Anonymous_Hugo",
"duration": 62
},
"icons": {
"icon6": "Male",
"icon3": "Donator",
"icon8": "Married - To Anonymous_Hugo",
"icon27": "Company - Employee of streamTV - hiring 33k man (Television Network)",
"icon9": "Faction - Member of The Watchers",
"icon15": "Hospital - Hospitalized by someone - 03:04:17 "
}
}
Any help would be greatly appreciated, thanks.
The error message is pretty straightforward. You're trying to deserialize object to List of RootObject.
Use this snippet:
void UpdateTornStats()
{
using (var webClient = new WebClient())
{
var json = new WebClient().DownloadString(ApiUrl);
var list = JsonConvert.DeserializeObject<PlayerStatistics.Stats.RootObject>(json);
Console.WriteLine(list.Count);
}
}
public class News
{
public string author { get; set; }
public string title { get; set; }
public DateTime timestamp{ get; set; }
public string content { get; set; }
public bool forstudents { get; set; }
public List<link> links { get; set; }
public List<imgs> imgs { get; set; }
}
public class link
{
public string name { get; set; }
public string value { get; set; }
}
public class imgs
{
public string name { get; set; }
public string value { get; set; }
}
This is my Model Description then i connect to the Server
var _esServer = new ElasticSearchServer("http://localhost:9200");
var _esIndex = _esServer.GetIndex("campusoffice");
var news = _esIndex.Get<News>("/news", int.MaxValue);
and it should get everything right but
he doesnt map the name and the value in the list elements
{
"author": "soulseak",
"title": "Awsome",
"timestamp": 20130201,
"content": "Erster",
"forstudents": true,
"links": {
"myhome": "http://test.de"
},
"imgs": {
"myhome": "http://test.de"
}
}
the question is how to tell him what to put in name and value that myhome is in name and the url in value
You can do something like this:
public class User {
public User(string json) {
var jsonObject = Json.Decode(json);
MyName = (string)jsonObject.user.name;
MyTeamName = (string)jsonObject.user.teamname;
MyEmail = (string)jsonObject.user.email;
Players = (DynamicJsonArray) jsonObject.user.players;
}
public string MyName{ get; set; }
public string MyTeamName { get; set; }
public string MyEmail{ get; set; }
public Array Players { get; set; }
}
But would need to assign the values manually.
Example using your model (0 index based only, you would need to write a loop) but using a direct RestFul call:
var url = "http://localhost:9200/campusoffice/news";
var client = new WebClient();
var json = client.DownloadString(url);
var jsonObject = Json.Decode(json);
var links = (DynamicJsonArray) jsonObject.links;
var imgs = (DynamicJsonArray) jsonObject.imgs;
var news = new News
{ author = (string)jsonObject.author,
links = new List<link>() };
var aLink = new link { name = (string)links[0].myhome, value =
(string)imgs[0].myhome };
news.links.Add(aLink);
I typed this roughly without compiling/testing but should give you an idea.