WP7 NullReferenceException deserializing JSON array - c#

I've been having trouble pulling JSON data from the web into my app. I'm trying to pull a name and image from the "featuredReleases" array. Here part of the JSON:
"featuredReleases":[
{
"id":860118,
"type":"release",
"name":"Back In Time",
"slug":"back-in-time",
"releaseDate":"2012-01-30",
"publishDate":"2012-01-30",
"exclusive":true,
"category":"Release",
"description":"Toolroom Records breaks new ground once again courtesy of the legendary drum and bass double act Liquid Kaos who have teamed up with vocalist Kirsty Hawkshaw for Back In Time, a drum and bass master class that will be taking over the airwaves and the clubs. Liquid Kaos need little introduction as owners of the legendary Breakbeat Kaos imprint and an impressive list of accolades between them that includes multiple UK Top 10 singles, a Mobo award and the support of the scenes most influential players Zane Lowe, Fabio & Grooverider, Mistajam and more. The most distinctive voice in dance music and a number 1 selling artist in her own right, Kirsty Hawkshaw completes this dream collaboration. Back In Time hooks you in with the haunting vocals of Kirsty Hawkshaw swirling above searing synths and atmospheric strings before dropping into organic grooves and a delectably warm bass. On the remix tip, Swedish star John Dahlb\u00e4ck provides a four to the floor electro workout, dubsteps rising star Cookie Monsta throws in a big, bass heavy re-rub whilst Toolrooms new wonder kid CaPa and Germanys deep house duo Kruse & N\u00fcrnberg complete a versatile package.",
"currentStatus":"New Release",
"catalogNumber":"TOOL12902Z",
"purchasable":true,
"images":{
"small":{
"width":30,
"height":30,
"url":"http:\/\/geo-media.beatport.com\/items\/imageCatalog\/4000000\/900000\/0\/9000\/500\/70\/4909578.jpg",
"secureUrl":"https:\/\/media.beatport.com\/items\/imageCatalog\/4000000\/900000\/0\/9000\/500\/70\/4909578.jpg"
},
"medium":{
"width":60,
"height":60,
"url":"http:\/\/geo-media.beatport.com\/items\/imageCatalog\/4000000\/900000\/0\/9000\/500\/70\/4909579.jpg",
"secureUrl":"https:\/\/media.beatport.com\/items\/imageCatalog\/4000000\/900000\/0\/9000\/500\/70\/4909579.jpg"
},
"large":{
"width":500,
"height":500,
"url":"http:\/\/geo-media.beatport.com\/items\/imageCatalog\/4000000\/900000\/0\/9000\/500\/80\/4909580.jpg",
"secureUrl":"https:\/\/media.beatport.com\/items\/imageCatalog\/4000000\/900000\/0\/9000\/500\/80\/4909580.jpg"
}
}
},
If you need to see the full JSON (its really long) here is the api to plug into a JSON Formatter. http://api.beatport.com/catalog/3/beatport/home
Here are my classes.
namespace Beatport.Classes
{
public class NewReleasesCharts //Root Object
{
public Metadata metadata { get; set; }
public ResultHome results = new ResultHome();
public IEnumerator<ResultHome> GetEnumerator()
{
return this.results.GetEnumerator();
}
}
public class ResultHome
{
public List<FeaturedReleases> featuredReleases { get; set; }
//public List<FeaturedCharts> featuredCharts { get; set; }
//public List<TopDownloads> topdownloads { get; set; }
//public List<MostPopularReleases> mostPopularReleases { get; set; }
//public List<Components> components { get; set; }
internal IEnumerator<ResultHome> GetEnumerator()
{
throw new NotImplementedException();
}
}
public class FeaturedReleases
{
public int id { get; set; }
public string type { get; set; }
public string name { get; set; }
public string slug { get; set; }
public ReleaseImage releaseImage { get; set; }
}
public class ReleaseImage
{
public ReleaseSmall releaseSmall { get; set; }
public ReleaseMedium releaseMedium { get; set; }
public ReleaseLarge releaseLarge { get; set; }
}
public class ReleaseMedium
{
public int width { get; set; }
public int height { get; set; }
public string url { get; set; }
public string secureUrl { get; set; }
}
Finally, here is my handler to deserialize the JSON (with json.net) and pull out the data.
UPDATED
// Deserialize home page data
void jsonHome_GetDataCompleted(object snder, DownloadStringCompletedEventArgs e)
{
try
{
NewReleasesCharts homeData = JsonConvert.DeserializeObject<NewReleasesCharts>(e.Result);
foreach (FeaturedReleases release in homeData.results.featuredReleases)
{
string releaseName = release.name;
string img = release.releaseImage.releaseMedium.url;
listGenres.Items.Add(releaseName);
listGenres.Items.Add(img);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I am now getting a json.net exception when trying to deserialize NewReleasesCharts.
Cannot deserialize JSON array (i.e. [1,2,3]) into type 'Beatport.Classes.ResultHome'.
The deserialized type must be an array or implement a collection interface like IEnumerable, ICollection or IList.
To force JSON arrays to deserialize add the JsonArrayAttribute to the type. Line 1, position 58.

You are very close to solution.
First, deserialize as
NewReleasesCharts homeData = JsonConvert.DeserializeObject<NewReleasesCharts>(e.Result)
Then change your class definitions as
public class FeaturedReleases
{
public int id { get; set; }
public string type { get; set; }
public string name { get; set; }
public string slug { get; set; }
public ReleaseImage images { get; set; }
}
public class ReleaseImage
{
public ReleaseSmall small { get; set; }
public ReleaseMedium medium { get; set; }
public ReleaseLarge large { get; set; }
}
and finally, your loop should be something like this
foreach (FeaturedReleases release in homeData.results.featuredReleases)
{
string releaseName = release.name;
string img = release.images.medium.url;
listGenres.Items.Add(releaseName);
listGenres.Items.Add(img);
}

Related

C# DTO List that consists of 2 other lists

Firstly, apologies if this seems basic, I am new to C#/dotnet and if the answer to this questions is somewhere obvious please point me in the right direction.
I have a DTO class with the following code
public class LessonDetailView : BaseResult
{
public long Id { get; set; }
public string Title { get; set; }
public List<LessonImagesListView> LessonImages { get; set; }
public List<LessonInstructionCardListView> InstructionCards { get; set; }
}
public class LessonImagesListView
{
public long Id { get; set; }
public string Title { get; set; }
public ImageDetailView Image { get; set; }
public LessonImagesListView()
{
Image = new ImageDetailView();
}
}
public class LessonInstructionCardListView
{
public long Id { get; set; }
public string Instructions { get; set; }
}
So I have 2 distinct types of object that I attach to the lesson and send to the frontend.
I will add that in the future I might have 6 different types of object.
These Images, or Instructions are also going to be displayed in a certain order on the front end so instead of sending them all separately I wanted to combine them all and send them in a new List LessonAssetsListView for example.
How can i create Lists in a DTO that combine 2 other lists ?
OR ... is this something I even need to do here ... and can i just do all this in my service.
Help appreciated.
You could simply define a type that composes both your existing and send a List of them
public class LessonAsset
{
public LessonImagesListView Image {get;set; }
public LessonInstructionCardListView Instruction {get;set;}
}
and then
public class LessonDetailView : BaseResult
{
public long Id { get; set; }
public string Title { get; set; }
public List<LessonAsset> LessonAssets { get; set; }
}

Is there a way to prevent Unexpected character that was encountered while parsing from JSON to C# and XAML error?

I was working on my project and I've come across this error that makes me abit frustrated for no reason:
[TheProblem][1]
[1]: https://i.stack.imgur.com/9Ajtn.png
I have been looking for many ways to solve this even on this very website but none worked so far for C# and Xaml. I am attempting to get JSON files into UPF to look like GUI.
My Vehicle Class:
public class Vehicle
{
[JsonPropertyName("make")]
public string Make { get; set; }
[JsonPropertyName("model")]
public string Model { get; set; }
[JsonPropertyName("VIN")]
public string VIN { get; set; }
[JsonPropertyName("CarType")]
public string CarType { get; set; }
[JsonPropertyName("Seatingcapacity")]
public int Seatingcapacity { get; set; }
[JsonPropertyName("DateObtained")]
public string DateObtained { get; set; }
[JsonPropertyName("NumOfMiles")]
public int NumOfMiles { get; set; }
[JsonPropertyName("InspectionNum")]
public int InspectionNum { get; set; }
[JsonPropertyName("InspectionTech")]
public string InspectionTech { get; set; }
[JsonPropertyName("InspectionDate")]
public string InspectionDate { get; set; }
[JsonPropertyName("InspectIssues")]
public string InspectIssues { get; set; }
[JsonPropertyName("RepairDiscard")]
public string RepairDiscard { get; set; }
[JsonPropertyName("EstPrice")]
public int EstPrice { get; set; }
[JsonPropertyName("EstimatedBy")]
public string EstimatedBy { get; set; }
[JsonPropertyName("EstimatedDate")]
public string EstimatedDate { get; set; }
[JsonPropertyName("SalePrice")]
public int SalePrice { get; set; }
[JsonPropertyName("SalesPerson")]
public string SalesPerson { get; set; }
[JsonPropertyName("SalesDate")]
public string SalesDate { get; set; }
[JsonPropertyName("NegotiatedPrice")]
public string NegotiatedPrice { get; set; }
[JsonPropertyName("NegotiatedPriceApproved")]
public string NegotiatedPriceApproved { get; set; }
}
public class Root
{
[JsonPropertyName("Vehicle")]
public List<Vehicle> Vehicle { get; set; }
}
public class VehicleManager
{
public static async Task<Root> GetVehicles()
{
string target = "Vechile.json";
Root vehicleJson = JsonConvert.DeserializeObject<Root>(target);
return vehicleJson;
}
}
My Vehicle JSON:
{
"make": "Audi",
"model": "A4",
"vin": "1B4HR28N41F524347",
"carType": "Sedan",
"Seatingcapacity": 4,
"DateObtained": "05/15/2010",
"NumOfMiles": 434567,
"InspectionNum": 312345,
"InspectionTech": "Windows",
"InspectionDate": "06/05/2016",
"InspectIssues": "No Issue",
"RepairDiscard": "No Discard",
"EstPrice": 700000,
"EstimatedBy": "Sannaha Vahanna",
"EstimatedDate": "04/27/2010",
"SalePrice": 500000,
"SalesPerson": "Sannaha Vahnna",
"SalesDate": "05/15/2010",
"NegotiatedPrice": "$45,000",
"NegotiatedPriceApproved": "Sannaha Vahnna"
}
}```
As well, my C#
```public sealed partial class MainPage : Page
{
public MainPage()
{
var Vehicles = VehicleManager.GetVehicles();
this.InitializeComponent();
}
private void VehicleGUI_ItemClick(object sender, ItemClickEventArgs e)
{
var vehicle= (Vehicle)e.ClickedItem;
this.Frame.Navigate(typeof(VehicleDetails), vehicle);
}
}```
What to do?
Look at the error message it's giving you. It says the unexpected character is 'V' at line 0 position 0. My guess is the data being passed is not actually the JSON data you think it is - perhaps it's some kind of string representation of a Vehicle (only guessing on that part from the 'V').
The best way to troubleshoot is throw your data being serialized into a local variable and set a break point right before you call the method to serialize. That way you can see exactly what is getting passed.
You may actually want to check out this question, you may be having a similar issue.

get deserialize json objects into list c#

I'm getting json string from webapi like this
{"page":1,"total_results":33,"total_pages":2,"results":
[{"vote_count":8017,"id":603,"video":false,"vote_average":7.9,"title":"The Matrix","popularity":7.82272,"poster_path":"\/lZpWprJqbIFpEV5uoHfoK0KCnTW.jpg","original_language":"en","original_title":"The Matrix","genre_ids":[28,878],"backdrop_path":"\/7u3pxc0K1wx32IleAkLv78MKgrw.jpg","adult":false,"overview":"Set in the 22nd century, The Matrix tells the story of a computer hacker who joins a group of underground insurgents fighting the vast and powerful computers who now rule the earth.","release_date":"1999-03-30"},
{"vote_count":2750,"id":605,"video":false,"vote_average":6.4,"title":"The Matrix Revolutions","popularity":5.073697,"poster_path":"\/sKogjhfs5q3azmpW7DFKKAeLEG8.jpg","original_language":"en","original_title":"The Matrix Revolutions","genre_ids":[12,28,53,878],"backdrop_path":"\/pdVHUsb2eEz9ALNTr6wfRJe5xVa.jpg","adult":false,"overview":"The human city of Zion defends itself against the massive invasion of the machines as Neo fights to end the war at another front while also opposing the rogue Agent Smith.","release_date":"2003-11-05"},
{"vote_count":0,"id":411948,"video":false,"vote_average":0,"title":"Matrix","popularity":1.004394,"poster_path":"\/cseRq8R9RGN66SNUgcD7RJAxBI7.jpg","original_language":"en","original_title":"Matrix","genre_ids":[],"backdrop_path":null,"adult":false,"overview":"John Whitney, Sr. (April 8, 1917 – September 22, 1995) was an American animator, composer and inventor, widely considered to be one of the fathers of computer animation.","release_date":"1971-05-18"}]}
I only want to get title from above string into list.
Here's my code
public List<string> ExtractMoviesList(string movieTitle)
{
using (var client = new HttpClient())
{
// HTTP GET
var response = client.GetAsync(string.Format("{0}{1}", movies_Url, movieTitle)).Result;
using (HttpContent content = response.Content)
{
var json = content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<List<Movies>>(json.Result);
return result.Select(p=>p.Title).ToList();
}
}
}
There's something wrong with this line of code: var result = JsonConvert.DeserializeObject<List<Movies>>(json.Result); after this line executed the var result is getting just null.
Your problem is that you are trying to deserialize your JSON as a List<T>, but the root object in your JSON is not an array, it's an object. This is easy to see if you format and indent your JSON using, say, https://jsonformatter.curiousconcept.com/:
{
"page":1,
"total_results":33,
"total_pages":2,
"results":[
{
"title":"The Matrix",
// Other fields
},
// Other movies
]
}
The data model to which you are binding your JSON must reflect this outer container object for deserialization to succeed. Luckily http://json2csharp.com/ or Paste JSON as Classes will generate one for you:
public class Movie
{
public string title { get; set; }
public int vote_count { get; set; }
public int id { get; set; }
public bool video { get; set; }
public double vote_average { get; set; }
public double popularity { get; set; }
public string poster_path { get; set; }
public string original_language { get; set; }
public string original_title { get; set; }
public List<object> genre_ids { get; set; }
public string backdrop_path { get; set; }
public bool adult { get; set; }
public string overview { get; set; }
public string release_date { get; set; }
}
public class RootObject
{
public int page { get; set; }
public int total_results { get; set; }
public int total_pages { get; set; }
public List<Movie> results { get; set; }
}
Now you can do:
var result = JsonConvert.DeserializeObject<RootObject>(json.Result);
return result.results.Select(m => m.title).ToList();
Incidentally, if you don't want to create a data model just to extract the titles from this JSON, you can use Json.NET's LINQ to JSON functionality to load and query the JSON directly:
var result = JToken.Parse(json.Result);
return result.SelectTokens("results[*].title").Select(t => (string)t).ToList();
Here I am using SelectTokens() with the JsonPATH wildcard operator [*] to find all entries in the results array.
Working .Net fiddle showing both options.

Deserialise JSON containing numeric key with Json.NET

I would like to deserialize the following JSON (using Json.NET) to an object, but cannot, as the class name would need to begin with a number.
An example of this is the Wikipedia article API. Using the API to provide a JSON response returns something like this. Note the "16689396" inside the "pages" key.
{
"batchcomplete":"",
"continue":{
"grncontinue":"0.893378504602|0.893378998188|35714269|0",
"continue":"grncontinue||"
},
"query":{
"pages":{
"16689396":{
"pageid":16689396,
"ns":0,
"title":"Jalan Juru",
"extract":"<p><b>Jalan Juru</b> (Penang state road <i>P176</i>) is a major road in Penang, Malaysia.</p>\n\n<h2><span id=\"List_of_junctions\">List of junctions</span></h2>\n<p></p>\n<p><br></p>"
}
}
}
}
How could I deserialize this JSON containing a number which changes based on the article?
It sounds like the Pages property in your Query class would just need to be a Dictionary<int, Page> or Dictionary<string, Page>.
Complete example with the JSON you've provided - I've had to guess at some of the name meanings:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
public class Root
{
[JsonProperty("batchcomplete")]
public string BatchComplete { get; set; }
[JsonProperty("continue")]
public Continuation Continuation { get; set; }
[JsonProperty("query")]
public Query Query { get; set; }
}
public class Continuation
{
[JsonProperty("grncontinue")]
public string GrnContinue { get; set; }
[JsonProperty("continue")]
public string Continue { get; set; }
}
public class Query
{
[JsonProperty("pages")]
public Dictionary<int, Page> Pages { get; set; }
}
public class Page
{
[JsonProperty("pageid")]
public int Id { get; set; }
[JsonProperty("ns")]
public int Ns { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("extract")]
public string Extract { get; set; }
}
class Test
{
static void Main()
{
string text = File.ReadAllText("test.json");
var root = JsonConvert.DeserializeObject<Root>(text);
Console.WriteLine(root.Query.Pages[16689396].Title);
}
}
Related question: Json deserialize from wikipedia api with c#
Essentially you need to changes from using a class for the pages to a dictionary, which allows for the dynamic nature of the naming convention.
Class definitions :
public class pageval
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
}
public class Query
{
public Dictionary<string, pageval> pages { get; set; }
}
public class Limits
{
public int extracts { get; set; }
}
public class RootObject
{
public string batchcomplete { get; set; }
public Query query { get; set; }
public Limits limits { get; set; }
}
Deserialization :
var root = JsonConvert.DeserializeObject<RootObject>(__YOUR_JSON_HERE__);
var page = responseJson.query.pages["16689396"];
You can implement your own DeSerializer or editing the JSON before you DeSerialize it.

WP8 JSON Deserialisation of Arrays nested in Arrays nested in Arrays

I want to do something quite simple.
I just want to take a JSON string (which I have) and populate a whole bunch of stuff with it.
The problem for me is that there are arrays hidden in array inside more arrays, and I can't get at my data.
I tried standard deserialization like so ...
var apiData = JsonConvert.DeserializeObject<RootObject>(json);
But this only lets me get into the top layer - what is in rootObject
I tried making a dictionary ...
Dictionary<string, dynamic> values = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
but that doesn't let me drill down either (or I can't make it).
I have set up my c# using json2c#
I've been all over the internet including here.
The closest I have got to creating anything close is an expandoObject
var converter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, converter);
which I can see from the debugger is keeping everything structured as I would like but I've no idea how to get some of the stuff out.
Long story short, its been two days now and I'm bashing my head against a brick wall.
I just want to be able to get the data out of the JSON string and I can't change that string as its not mine.
public class NewsArticlesList
{
public string title { get; set; }
public string link { get; set; }
public string source { get; set; }
public string snippet { get; set; }
}
public class jobsList
{
public string title { get; set; }
public string titleLinkUrl { get; set; }
public List<object> relatedSearchesList { get; set; }
public string formattedTraffic { get; set; }
public int trafficBucketLowerBound { get; set; }
public int interestLevel { get; set; }
public string interestColor { get; set; }
public List<NewsArticlesList> newsArticlesList { get; set; }
public double startTime { get; set; }
public string shareUrl { get; set; }
public string date { get; set; }
}
public class jobsByDateList
{
public string date { get; set; }
public string formattedDate { get; set; }
public List<jobsList> jobsList { get; set; }
}
public class RootObject
{
public string summaryMessage { get; set; }
public double dataUpdateTime { get; set; }
public List<jobsByDateList> jobsByDateList { get; set; }
public string oldestVisibleDate { get; set; }
public bool lastPage { get; set; }
}
My problem is these lists inside lists inside lists.
I can get to jobsListByDate.formattedDate but I can't get anywhere near jobsListByDate.jobsList.titleLinkUrl let alone inside the NewsArticlesList to those sources.
Apologies if this is super-easy (I hope it is) but I'm a WP8 noob.
I know there are similar threads on SO, but none of them seem to deal with such deep arrays.
I was not stipulating which branch to go down and so it was confused.
System.Diagnostics.Debug.WriteLine(apiData.jobsByDateList[0].jobsList[0].interestLevel);
I was trying to get in using
System.Diagnostics.Debug.WriteLine(apiData.jobsByDateList.jobsList.interestLevel);
and intellisense was freaking out.
With the [0] I'm now able to drill in just fine and don't need the expandoobject. Just needed to sleep on it. :-)

Categories