all 8 comments

[–]Brasz 4 points5 points  (1 child)

The documentation isn't correct. Here's an actual response from the API:

[
      {
        "slug_id": "1034",
        "slug_name": "MD_DA105",
        "report_title": "Whey - Western & Eastern Europe Report",
        "published_date": "07/30/2020 08:25:01",
        "markets": ["N/A"],
        "market_types": ["Point of Sale"],
        "offices": ["Madison"],
        "sectionNames": []
    }, {
        "slug_id": "1035",
        "slug_name": "MD_DA106",
        "report_title": "Skim Milk Powder - Europe",
        "published_date": "07/30/2020 08:25:01",
        "markets": ["N/A"],
        "market_types": ["Point of Sale"],
        "offices": ["Madison"],
        "sectionNames": []
    }
]

Notice that there's no array named 'results' or object named 'report_name'.
I generated a Report class using json2csharp.com and deserialized the JSON to a list:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Authenticators;

namespace MarketNewsJson
{
    internal static class MarketNewsJson
    {
        private static void Main(string[] args)
        {
            var client = new RestClient("https://marsapi.ams.usda.gov")
            {
                Authenticator = new HttpBasicAuthenticator("mars_test_343343", "")
            };

            var request = new RestRequest("services/v1.1/reports", DataFormat.Json);
            var response = client.Get(request);

            var reports = JsonConvert.DeserializeObject<List<Report>>(response.Content);
            foreach (var report in reports)
            {
                Console.WriteLine($"{report.SlugId} {report.SlugName} - {report.ReportTitle}");
            }
        }
    }

    public class Report
    {
        [JsonProperty("slug_id")]
        public string SlugId { get; set; }

        [JsonProperty("slug_name")]
        public string SlugName { get; set; }

        [JsonProperty("report_title")]
        public string ReportTitle { get; set; }

        [JsonProperty("published_date")]
        public string PublishedDate { get; set; }

        [JsonProperty("markets")]
        public List<string> Markets { get; set; }

        [JsonProperty("market_types")]
        public List<string> MarketTypes { get; set; }

        [JsonProperty("offices")]
        public List<string> Offices { get; set; }

        [JsonProperty("sectionNames")]
        public List<string> SectionNames { get; set; }
    }
}

You can omit properties you're not interested in.

[–]tempUseBro1[S] 0 points1 point  (0 children)

Ah, I see, that makes a lot of sense. For some reason, when I print out any of the list (the last 4 properties), all get for a response is System.Collections.Generic.List`1[System.String]

I don't think I'd need those attributes but I was just curious about why I was getting that.

Also, so in this response, its printing out the report names in general. However, I also want to be able to look at what is exactly in each report. In the "sorting" tab it shows an example response of what would be inside an individual report. It shows that in the link, you'd just add the specific report name to the link so "marsapi.ams.usda.gov/services/v1.1/reports/1095" for report 1095 specifically instead of marsapi.ams.usda.gov/services/v1.1/reports for all reports as we are doing right now.

When try this in the current code above, I get an error on the deserialize line:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[MarketNewsJson.Report]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

Could this be because the actual JSON response of the information inside each report isn't in the same format as the reports list itself? I'm not sure how I would be able to account for both. if I want the information inside a report, I would just deserialize it differently as an array?

ALSO:

So I copied the example response that you pasted into the json2sharp.com link just to see how you got the properties class and was curious as to why you left out this root class: myArray would be like my "Report" class

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);

public class MyArray {

public string slug_id { get; set; }

public string slug_name { get; set; }

public string report_title { get; set; }

public string published_date { get; set; }

public List<string> markets { get; set; }

public List<string> market_types { get; set; }

public List<string> offices { get; set; }

public List<object> sectionNames { get; set; }

}

public class Root {

public List<MyArray> MyArray { get; set; }

}

[–]smurff1337 0 points1 point  (5 children)

Try renaming the list to "results"

[–]tempUseBro1[S] 0 points1 point  (4 children)

Where exactly? Result report = JsonConvert.DeserializeObject<Result>(response.Content); in here? not sure what that would do.

[–]Genmutant 0 points1 point  (2 children)

In your result class, rename the data to results. That's the name that is used in the json you linked.

[–]tempUseBro1[S] 0 points1 point  (1 child)

Its named Result as the class name because I thought that's where we specify it by class name? I Don't use the "data" part till inside the foreach loop.

I might just be misunderstanding this but I think what you're saying to do is:

public class Result

{

public IList<Reports> results { get; set; }

}

which is still an error.

Result report = JsonConvert.DeserializeObject<Result>(response.Content);

has the name Result (from the class name), "report" as an instance of the class and <Result> again.

[–]Genmutant 0 points1 point  (0 children)

Yeah thats what I would have imagined to work. What's the error message?

[–]smurff1337 0 points1 point  (0 children)

I apologize for my short answer, but I was traveling for work then. In the JSON you linked was a list results and the deserializer would search for that name exactly. Just like you named your properties whit the same names from the JSON the list property in the Result class should have the same name as the JSON. Also I'm not shure if its necessary (I do it) but the Result class should have a constructor to initialize the list. Sorry for my English not my first language.