Retrieving values of fields in a list - c#

I have the class "Alerts", which contains some returned information from Wunderground's API. I then have another class inside "Alerts", "Alert". My code looks like this:
public class Alerts
{
public class Features
{
public int alerts { get; set; }
}
public class Response
{
public string version { get; set; }
public string termsofService { get; set; }
public Features features { get; set; }
}
public class ZONED
{
public string state { get; set; }
public string ZONE { get; set; }
}
public class StormBased
{
}
public class Alert
{
public string type { get; set; }
public string description { get; set; }
public string date { get; set; }
public string date_epoch { get; set; }
public string expires { get; set; }
public string expires_epoch { get; set; }
public string message { get; set; }
public string phenomena { get; set; }
public string significance { get; set; }
public List<ZONED> ZONES { get; set; }
public StormBased StormBased { get; set; }
}
public class RootObject
{
public Response response { get; set; }
public string query_zone { get; set; }
public List<Alert> alerts { get; set; }
}
public class AlertsUpdateState
{
public HttpWebRequest AsyncRequest { get; set; }
public HttpWebResponse AsyncResponse { get; set; }
}
}
I create a RootObject when the app starts, and later use JSON to empty values. The call returns "response", "query_zone", and "alerts". Now the last one is a List of type Alert, which contains type, description, etc. of an issued alert.
So I have this list stored as alertVar. This has several methods, including count. I can figure out how many alerts are issued, but I'm not sure how to move on.
How do I retrieve the string values (such as type) with this list?

Assuming alertVar is your list of Alert, you can do something like:
string some_string;
foreach (var alert in alertVar)
{
some_string += alert.type + ", ";
}
This will add all the types to a long string (some_string).
You can do the same for whichever property you want ...

foreach (var alert in alerts)
{
var type = alert.type;
var description = alert.description
}
That is a basic example of how you use the item you are looping over.

Related

Convert JSON Request to C# object and send Response back in different JSON format

I am making a call to a webservice and getting following Json Request
{"handler":{"name":"abc"},"intent":{"name":"actions.intent.MAIN","params":{},"query":"Mit Google sprechen"},"scene":{"name":"actions.scene.START_CONVERSATION","slotFillingStatus":"UNSPECIFIED","slots":{},"next":{"name":"Start_Frage"}},"session":{"id":"ABwppHHVumDrliLJaLSikS6KnIlN7yYv6Z4XJCOYzEZt8Fr08RH6r0wtM2-E0v40lS2p1YosTDfpSCd5Lw","params":{},"typeOverrides":[],"languageCode":""},"user":{"locale":"de-DE","params":{},"accountLinkingStatus":"ACCOUNT_LINKING_STATUS_UNSPECIFIED","verificationStatus":"VERIFIED","packageEntitlements":[],"gaiamint":"","permissions":[],"lastSeenTime":"2021-04-01T10:06:59Z"},"home":{"params":{}},"device":{"capabilities":["SPEECH","RICH_RESPONSE","LONG_FORM_AUDIO"]}}
I used https://json2csharp.com/ to convert my Json String to C# Classes
public class Handler
{
public string name { get; set; }
}
public class Params
{
}
public class Intent
{
public string name { get; set; }
public Params #params { get; set; }
public string query { get; set; }
}
public class Slots
{
}
public class Next
{
public string name { get; set; }
}
public class Scene
{
public string name { get; set; }
public string slotFillingStatus { get; set; }
public Slots slots { get; set; }
public Next next { get; set; }
}
public class Session
{
public string id { get; set; }
public Params #params { get; set; }
public List<object> typeOverrides { get; set; }
public string languageCode { get; set; }
}
public class User
{
public string locale { get; set; }
public Params #params { get; set; }
public string accountLinkingStatus { get; set; }
public string verificationStatus { get; set; }
public List<object> packageEntitlements { get; set; }
public string gaiamint { get; set; }
public List<object> permissions { get; set; }
public DateTime lastSeenTime { get; set; }
}
public class Home
{
public Params #params { get; set; }
}
public class Device
{
public List<string> capabilities { get; set; }
}
public class RequestJson
{
public Handler handler { get; set; }
public Intent intent { get; set; }
public Scene scene { get; set; }
public Session session { get; set; }
public User user { get; set; }
public Home home { get; set; }
public Device device { get; set; }
}
I need to send back a JSON Respond that is formatted that way
{"responseJson": {"session": {"id": "ABwppHF4mhTR8RAjnFSt7me_NFR1hRKHY5N6X0kfONIcz_VVPUOmR8VddWVJ3GM3G8ix3OR3O1Ew2wbldc5cRziYebVA","params": {},"languageCode": ""},"prompt": {"override": false,"firstSimple": {"speech": "Stellen Sie eine Frage","text": ""}}}}
https://json2csharp.com/ that results into this object structure
public class Params
{
}
public class Session
{
public string id { get; set; }
public Params #params { get; set; }
public string languageCode { get; set; }
}
public class FirstSimple
{
public string speech { get; set; }
public string text { get; set; }
}
public class Prompt
{
public bool #override { get; set; }
public FirstSimple firstSimple { get; set; }
}
public class ResponseJson
{
public Session session { get; set; }
public Prompt prompt { get; set; }
}
}
My current code looks like this:
I get an nullreferenceexception if i do it that way. I cant set any Values in the RespondJson object. I am new to programming. I would be very grateful for help
[HttpPost]
public async Task<IActionResult> PostWebHook([FromBody] RequestJson request)
{
ResponseJson response = new ResponseJson();
string body;
using (var reader = new StreamReader(Request.Body))
{
body = await reader.ReadToEndAsync();
// => doesnt work that way I get a nullreferenceexception
response.session.id = request.session.id; //nullreferenceexception
response.prompt.#override = false;
response.prompt.firstSimple.speech = "Test123";
//
}
return Ok(response);
}
}
How would i do that?
In short: I receive a request in JSON,but later on I need to send a response back in another JSON format.
The best way it is have two separate models. One pre request and second per response. Ofcourse you can reuse some classes anuse in Both models. In your json you can reuse the session object and then you have to create new class which will be represent prompt object.
Example of your Response object:
public class Params
{
}
public class Session
{
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("params")]
public Params Params { get; set; }
[JsonPropertyName("languageCode")]
public string LanguageCode { get; set; }
}
public class FirstSimple
{
[JsonPropertyName("speech")]
public string Speech { get; set; }
[JsonPropertyName("text")]
public string Text { get; set; }
}
public class Prompt
{
[JsonPropertyName("override")]
public bool Override { get; set; }
[JsonPropertyName("firstSimple")]
public FirstSimple FirstSimple { get; set; }
}
public class ResponseJson
{
[JsonPropertyName("session")]
public Session Session { get; set; }
[JsonPropertyName("prompt")]
public Prompt Prompt { get; set; }
}
public class Response
{
[JsonPropertyName("responseJson")]
public ResponseJson ResponseJson { get; set; }
}

Problem trying to deserialize a json with a model

I am trying to deserialize a json (using Newtonsoft.Json), i created the classes, but in json code there is a variable that i don't know if it is corrected or i don't know how to deserialize.
I am getting a null exception on line : MessageBox.Show(root.matriculations._14000.name)
private void btnImportaDados_Click(object sender, EventArgs e)
{
string getDataUrl = "https://xxx.xxx.com/api/matriculations/get.json?entity_code=14000";
try
{
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString(getDataUrl);
var root = JsonConvert.DeserializeObject<Rootobject>(json);
MessageBox.Show(root.matriculations._14000.name);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public class Rootobject
{
public Matriculations matriculations { get; set; }
}
public class Matriculations
{
public _14000 _14000 { get; set; }
}
public class _14000
{
public string entity_code { get; set; }
public string name { get; set; }
public string street { get; set; }
public string local { get; set; }
public string postal_code { get; set; }
public string sub_postal_code { get; set; }
public string phone1 { get; set; }
public object phone2 { get; set; }
public string email1 { get; set; }
public object email2 { get; set; }
public string entity_code_2 { get; set; }
public string courseaction_ref { get; set; }
public string courseaction_id { get; set; }
public string course_code { get; set; }
public string course { get; set; }
public Billingorderplan[] billingorderplans { get; set; }
}
public class Billingorderplan
{
public string id { get; set; }
public string paid { get; set; }
public string date { get; set; }
public object obs { get; set; }
public object payment_doc_num { get; set; }
public string value { get; set; }
public string description { get; set; }
public string entity_code { get; set; }
public object paid_date { get; set; }
}
The result(json data) from the url is:
{"matriculations":{"14000":{"entity_code":"14000","name":"Fabio Danilson Sivone Antonio","street":"Rua Dr. Pereira Jardim, Bl. 3 - 25 - 4 B","local":"Luanda","postal_code":"2685","sub_postal_code":"093","phone1":"923810539","phone2":null,"email1":"fabiodanilson1#hotmail.com","email2":null,"entity_code_2":"9957","courseaction_ref":"EPCE_01","courseaction_id":"1828","course_code":"EPCE","course":"Especializa\u00e7\u00e3o Avan\u00e7ada em Investiga\u00e7\u00e3o de Crime Econ\u00f3mico [E-learning]","billingorderplans":[{"id":"298","paid":"0","date":"2020-05-06","obs":null,"payment_doc_num":null,"value":"0.00","description":"Inscri\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"299","paid":"0","date":"2019-11-21","obs":null,"payment_doc_num":null,"value":"0.00","description":"1\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"300","paid":"0","date":"2019-12-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"2\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"301","paid":"0","date":"2020-01-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"3\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"302","paid":"0","date":"2020-02-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"4\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"303","paid":"0","date":"2020-03-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"5\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"304","paid":"0","date":"2020-04-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"6\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"305","paid":"0","date":"2020-05-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"7\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"306","paid":"0","date":"2020-06-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"8\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"16595","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null},{"id":"16596","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"45.00","description":"EExt - Teste","entity_code":"14000","paid_date":null},{"id":"16597","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null},{"id":"16598","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"45.00","description":"EExt - Teste","entity_code":"14000","paid_date":null},{"id":"16599","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null},{"id":"16601","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"45.00","description":"EExt - Teste","entity_code":"14000","paid_date":null},{"id":"16600","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null}]}}}
But that "14000" is a varible value depending from the parameter passed.
How can i do it?
Thank You.
Since 14000 cannot be a variable name you will have to resort to some manual intervention to capture that dynamic value. The cleanest way is to remove the Matriculations class and replace it with Dictionary<int, _14000> (or Dictionary<string, _14000>).
public class Rootobject
{
public Dictionary<int, _14000> matriculations { get; set; }
}
This will ensure that the key is captured correctly even if it is a number. You can read the object from the dictionary's values as such: root.matriculations.Values.First().name. (Remember to import System.Linq for using .First().)
For clarity you can rename _14000 to something more descriptive.
You do not have _14000 in returned JSON but 14000 under matriculations.

Deserializing a nested JSON string, cannot access properties

I am having issues deserializing a nested JSON array from the Genius lyric website API. I formulated the object using http://json2csharp.com. When I deserialize the object, I am unable to access the properties inside of the class, which wasn't entirely unexpected, I am just not sure how to properly design an actual solution to the problem. The JSON object conversions work fine when they are not nested.
What would be the best way to go about handling this?
Here is the conversion code:
string test = await G.SearchGeniusASync(textBox1.Text);
var data = JsonConvert.DeserializeObject<GeniusApiObject>(test);
Here is my class:
class GeniusApiObject
{
public class Meta
{
public int status { get; set; }
}
public class Stats
{
public bool hot { get; set; }
public int unreviewed_annotations { get; set; }
public int concurrents { get; set; }
public int pageviews { get; set; }
}
public class PrimaryArtist
{
public string api_path { get; set; }
public string header_image_url { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public bool is_meme_verified { get; set; }
public bool is_verified { get; set; }
public string name { get; set; }
public string url { get; set; }
public int iq { get; set; }
}
public class Result
{
public int annotation_count { get; set; }
public string api_path { get; set; }
public string full_title { get; set; }
public string header_image_thumbnail_url { get; set; }
public string header_image_url { get; set; }
public int id { get; set; }
public int lyrics_owner_id { get; set; }
public string lyrics_state { get; set; }
public string path { get; set; }
public int? pyongs_count { get; set; }
public string song_art_image_thumbnail_url { get; set; }
public Stats stats { get; set; }
public string title { get; set; }
public string title_with_featured { get; set; }
public string url { get; set; }
public PrimaryArtist primary_artist { get; set; }
}
public class Hit
{
public List<object> highlights { get; set; }
public string index { get; set; }
public string type { get; set; }
public Result result { get; set; }
}
public class Response
{
public List<Hit> hits { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
public Response response { get; set; }
}
}
This is the source for the SearchGeniusASync method in case it is helpful:
public async Task<string>SearchGeniusASync(string searchParameter)
{
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", clientAccessToken);
var result = await httpClient.GetAsync(new Uri("https://api.genius.com/search?q=" + searchParameter), HttpCompletionOption.ResponseContentRead);
var data = await result.Content.ReadAsStringAsync();
return data;
}
This is the scope I am given access to:
https://i.imgur.com/9mZMvfp.png
Here's a sample JSON request in plaintext:
https://pastebin.com/iA8dQafW
GeniusApiObject is not needed in the code, but I'll leave it in just because it helps organize things (may be that something else also has a RootObject from the auto-generator).
The problem is that you are trying to deserialize to what is just an empty class, the class itself has no properties, so you can't deserialize to it. You need to deserialize to the GeniusApiObject.RootObject.
var data = JsonConvert.DeserializeObject<GeniusApiObject.RootObject>(test);
Will deserialize to the .RootObject subclass. This is verified working:
Where I'm using File.ReadAllText("test.json") to load the example API data provided.
Here is a .NET Fiddle showing it working (without the root object and only one song in the response). Thanks to #maccttura.

Windows Phone Parse json data? from Url with user input?

I Followed this to Create Restful Web Services which display JSON as OutPut from the MySQL Data base.
I Successfully Done it, But Here I Have nearly 100 Tables in Database with different name
And I am Getting This kind of Json Data
{"WindowsResult":[{"ID":9,"TYPE":"WindowsPhone","TITLE":"XYZ","PRICE":"$0","IMAGE":"Post1.jpg"}],"success":3}
this another result
{"SonyResult":[{"ID":3,"TYPE":"SonyXperia","TITLE":"XYZ","PRICE":"$0","IMAGE":"Post2.jpg"}],"success":3}
this another one
{"SamsungResult":[{"ID":1,"TYPE":"Samsung","TITLE":"XYZ","PRICE":"$0","IMAGE":"Post3.jpg"}],"success":3}
For this I am parsing a JSON data form a url
like localhost/Service1.svc/windows or localhost/Service1.svc/sony like that
Here it should Take with a user input..
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
string Data = txtData.Text;
string ServiceUri = "http://lhost:30576/Service1.svc/"
+ "Data" + "/";
WebClient proxy = new WebClient();
proxy.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(proxy_DownloadStringCompleted);
proxy.DownloadStringAsync(new Uri(ServiceUri));
}
But I am Confused at Here
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
foreach (var TYPE in rootObject.SonyResult)
{
Console.WriteLine(type.TITLE);
}
}
what should be at Root object
for some Results I have SamsungResult as Root Object like that.
Please suggest Me Regarding this..
Update
when I enter the a url like http://www.google.com/service1.scv/sony
I am getting
{"SonyResult":[{"ID":3,"TYPE":"SonyXperia","TITLE":"XYZ","PRICE":"$0","IMAGE":"Post2.jpg"}],"success":3}
like that every brand I have one result Not All in one string..
K bro the problem is in your json data
{"Mobiles":[
{"SonyResult":[{"ID":3,"TYPE":"SonyXperia","TITLE":"XYZ","PRICE":"$0","IMAGE":"Post2.jpg"}],"success":3},
{"WindowsResult":[{"ID":9,"TYPE":"WindowsPhone","TITLE":"XYZ","PRICE":"$0","IMAGE":"Post1.jpg"}],"success":3}
]}
Since you hadn't specified a Root object name for our tables so json was using your table names as root objects.
Its C# class will be
public class SonyResult
{
public int ID { get; set; }
public string TYPE { get; set; }
public string TITLE { get; set; }
public string PRICE { get; set; }
public string IMAGE { get; set; }
}
public class WindowsResult
{
public int ID { get; set; }
public string TYPE { get; set; }
public string TITLE { get; set; }
public string PRICE { get; set; }
public string IMAGE { get; set; }
}
public class Mobile
{
public List<SonyResult> SonyResult { get; set; }
public int success { get; set; }
public List<WindowsResult> WindowsResult { get; set; }
}
public class RootObject
{
public List<Mobile> Mobiles { get; set; }
}
Hope that solved your problem.
Update
For ur received query the C# class is going to be
public class SonyResult
{public int ID { get; set; }
public string TYPE { get; set; }
public string TITLE { get; set; }
public string PRICE { get; set; }
public string IMAGE { get; set; }
}
public class RootObject
{
public List<SonyResult> SonyResult { get; set; }
public int success { get; set; }
}
Now since for each different models you are getting different queries where each are an array of its own with no common object name. So for each different model the root object class will differ.
I havent tried it as I dont have access to your code but try if this format works(Since I havent tried this so I have my doubts if this will work or not).
public class SonyResult
{
public int ID { get; set; }
public string TYPE { get; set; }
public string TITLE { get; set; }
public string PRICE { get; set; }
public string IMAGE { get; set; }
}
public class WindowsResult
{
public int ID { get; set; }
public string TYPE { get; set; }
public string TITLE { get; set; }
public string PRICE { get; set; }
public string IMAGE { get; set; }
}
public class RootObject
{
public List<SonyResult> SonyResult { get; set; }
public int success { get; set; }
public List<WindowsResult> WindowsResult { get; set; }
}

JSON.NET Resolving Nested Data Types

I'm new to JSON.NET, and I've been playing with the new Marvel API that was recently released.
When I call this API it will return the following JSON Data Structure:-
{
"code": 200,
"status": "Ok",
"etag": "f0fbae65eb2f8f28bdeea0a29be8749a4e67acb3",
"data":
{
"offset": 0,
"limit": 20,
"total": 30920,
"count": 20,
"results": [{array of objects}}]
}
}
I can create Classes for this Data like this :
public class Rootobject
{
public int code { get; set; }
public string status { get; set; }
public string etag { get; set; }
public Data data { get; set; }
}
public class Data
{
public int offset { get; set; }
public int limit { get; set; }
public int total { get; set; }
public int count { get; set; }
public Result[] results { get; set; }
}
public class Result
{
}
Now, my issue. The Results that come back from the API can relate to different Objects, it could be results relating to Characters, Comics, Series etc. The objects all hold different properties.
I need to be able to swap out the Result Class properties based on the Entity Type that the results relate too?
Can this actually be done?
You can use var jObj = JObject.Parse(jsonString) then discover what object type it is by which properties are available on the object.
jObj["someComicSpecificProperty"] != null
However this is not full proof and will need to be done on a per object basis for the results array.
An alternate approach I have seen people use is to have a property on the object that is "typeName".
However the root cause of this problem is that you are trying to strongly type a property that is not strongly typed. I would really recommend splitting these different types of results out into different properties so that you don't have this problem.
As promised, I've posted the anser to this problem. It turns out that the JSON response has nested data covering all related data-types, very much like a relational database.
I found something really cool, I basically made a request to the API and converted its response to a string. I then used the debugger to take a copy of the contents to the clipboard.
I created a new Class and Called it MarvelResponse.
I added the NewtonSoft.Json directive to the file, and used the Paste Special option from Edit Menu in VS2012. Here you can paste the option "Paste as JSON CLasses".
After some minor tweaking here is what it provided :-
namespace Kaiser.Training.Data.JSONClasses
{
public class MarvelResponse
{
public int code { get; set; }
public string status { get; set; }
public string etag { get; set; }
public Data data { get; set; }
}
public class Data
{
public int offset { get; set; }
public int limit { get; set; }
public int total { get; set; }
public int count { get; set; }
public Result[] results { get; set; }
}
public class Result
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public DateTime modified { get; set; }
public Thumbnail thumbnail { get; set; }
public string resourceURI { get; set; }
public Comics comics { get; set; }
public Series series { get; set; }
public Stories stories { get; set; }
public Events events { get; set; }
public Url[] urls { get; set; }
}
public class Thumbnail
{
public string path { get; set; }
public string extension { get; set; }
}
public class Comics
{
public int available { get; set; }
public string collectionURI { get; set; }
public ComicResourceUriItem[] items { get; set; }
public int returned { get; set; }
}
public class ComicResourceUriItem
{
public string resourceURI { get; set; }
public string name { get; set; }
}
public class Series
{
public int available { get; set; }
public string collectionURI { get; set; }
public SeriesResourceItem[] items { get; set; }
public int returned { get; set; }
}
public class SeriesResourceItem
{
public string resourceURI { get; set; }
public string name { get; set; }
}
public class Stories
{
public int available { get; set; }
public string collectionURI { get; set; }
public StoriesResourceItem[] items { get; set; }
public int returned { get; set; }
}
public class StoriesResourceItem
{
public string resourceURI { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class Events
{
public int available { get; set; }
public string collectionURI { get; set; }
public EventsResourceUriItem[] items { get; set; }
public int returned { get; set; }
}
public class EventsResourceUriItem
{
public string resourceURI { get; set; }
public string name { get; set; }
}
public class Url
{
public string type { get; set; }
public string url { get; set; }
}
}
This was a huge help! Hope someone else finds it useful.

Categories

Resources