Search code examples
c#json.netresteasy

Get only a few properties from httprequest with newtonsoft.json


I need to parse such response from google:

https://trends.google.com/trends/api/explore?hl=en-US&tz=-180&req=%7B%22comparisonItem%22:%5B%7B%22keyword%22:%22react%22,%22geo%22:%22%22,%22time%22:%22today+12-m%22%7D%5D,%22category%22:0,%22property%22:%22%22%7D&tz=-180

Response looks smth like this

other properties: ...
widgets: [{token: ""},...]

For sending requests I'm using RestEase. RestEase response from Google I'd like to map to my model

public class TokenResult
{
    [JsonProperty("widgets[0].token")]
    public string Token { get; set; }
}

I'm getting an error when restease is trying to parse response. So how can got only a token from the very first widget?


Solution

  • After a discussion on the requirement of your problem, you can use dynamic to get your token from the JSON string without using a model class. A working demo is here: https://dotnetfiddle.net/bGL8aZ

    using System;
    using Newtonsoft.Json;
    
    public class Program
    {
        public static void Main()
        {
            string json=@"{'widgets':[{'request':{'time':'2018-07-09 2019-07-09','resolution':'WEEK','locale':'en-US','comparisonItem':[{'geo':{},'complexKeywordsRestriction':{'keyword':[{'type':'BROAD','value':'react'}]}}],'requestOptions':{'property':'','backend':'IZG','category':0}},'lineAnnotationText':'Search interest','bullets':[{'text':'react'}],'showLegend':false,'showAverages':false,'helpDialog':{'title':'Interest over time','content':'Numbers represent search interest relative to the highest point on the chart for the given region and time. A value of 100 is the peak popularity for the term. A value of 50 means that the term is half as popular. A score of 0 means there was not enough data for this term.'},'token':'APP6_UEAAAAAXSXKDwW-kwcTrkXhBuCj17xOewtWmROU','id':'TIMESERIES','type':'fe_line_chart','title':'Interest over time','template':'fe','embedTemplate':'fe_embed','version':'1','isLong':true,'isCurated':false},{'request':{'geo':{},'comparisonItem':[{'time':'2018-07-09 2019-07-09','complexKeywordsRestriction':{'keyword':[{'type':'BROAD','value':'react'}]}}],'resolution':'COUNTRY','locale':'en-US','requestOptions':{'property':'','backend':'IZG','category':0}},'geo':'world','resolution':'countries','searchInterestLabel':'Search interest','displayMode':'regions','helpDialog':{'title':'Interest by region','content':'See in which location your term was most popular during the specified time frame. Values are calculated on a scale from 0 to 100, where 100 is the location with the most popularity as a fraction of total searches in that location, a value of 50 indicates a location which is half as popular. A value of 0 indicates a location where there was not enough data for this term. \u003cp\u003e\u003cp\u003e \u003cb\u003eNote:\u003c/b\u003e A higher value means a higher proportion of all queries, not a higher absolute query count. So a tiny country where 80% of the queries are for \'bananas\' will get twice the score of a giant country where only 40% of the queries are for \'bananas\'.','url':'https://support.google.com/trends/answer/4355212'},'color':'PALETTE_COLOR_1','index':0,'bullet':'react','token':'APP6_UEAAAAAXSXKD-rIwyhC21Abw8P2nPfb7AGhxrZ1','id':'GEO_MAP','type':'fe_geo_chart_explore','title':'Interest by region','template':'fe','embedTemplate':'fe_embed','version':'1','isLong':true,'isCurated':false},{'request':{'restriction':{'geo':{},'time':'2018-07-09 2019-07-09','originalTimeRangeForExploreUrl':'today 12-m','complexKeywordsRestriction':{'keyword':[{'type':'BROAD','value':'react'}]}},'keywordType':'ENTITY','metric':['TOP','RISING'],'trendinessSettings':{'compareTime':'2017-07-08 2018-07-08'},'requestOptions':{'property':'','backend':'IZG','category':0},'language':'en'},'helpDialog':{'title':'Related topics','content':'Users searching for your term also searched for these topics. You can view by the following metrics: \u003cp\u003e* \u003cb\u003eTop\u003c/b\u003e - The most popular topics. Scoring is on a relative scale where a value of 100 is the most commonly searched topic and a value of 50 is a topic searched half as often as the most popular term, and so on. \u003cp\u003e* \u003cb\u003eRising\u003c/b\u003e - Related topics with the biggest increase in search frequency since the last time period. Results marked \'Breakout\' had a tremendous increase, probably because these topics are new and had few (if any) prior searches.'},'color':'PALETTE_COLOR_1','keywordName':'react','token':'APP6_UEAAAAAXSXKD9wlRrdtpbUyYXxko216LXZt21ra','id':'RELATED_TOPICS','type':'fe_related_searches','title':'Related topics','template':'fe','embedTemplate':'fe_embed','version':'1','isLong':false,'isCurated':false},{'request':{'restriction':{'geo':{},'time':'2018-07-09 2019-07-09','originalTimeRangeForExploreUrl':'today 12-m','complexKeywordsRestriction':{'keyword':[{'type':'BROAD','value':'react'}]}},'keywordType':'QUERY','metric':['TOP','RISING'],'trendinessSettings':{'compareTime':'2017-07-08 2018-07-08'},'requestOptions':{'property':'','backend':'IZG','category':0},'language':'en'},'helpDialog':{'title':'Related queries','content':'Users searching for your term also searched for these queries. You can sort by the following metrics: \u003cp\u003e* \u003cb\u003eTop\u003c/b\u003e - The most popular search queries. Scoring is on a relative scale where a value of 100 is the most commonly searched query, 50 is a query searched half as often as the most popular query, and so on. \u003cp\u003e* \u003cb\u003eRising\u003c/b\u003e - Queries with the biggest increase in search frequency since the last time period. Results marked \'Breakout\' had a tremendous increase, probably because these queries are new and had few (if any) prior searches.','url':'https://support.google.com/trends/answer/4355000'},'color':'PALETTE_COLOR_1','keywordName':'react','token':'APP6_UEAAAAAXSXKD10s1DrnqESw00VH8rfqAEq4ZjmA','id':'RELATED_QUERIES','type':'fe_related_searches','title':'Related queries','template':'fe','embedTemplate':'fe_embed','version':'1','isLong':false,'isCurated':false}],'keywords':[{'keyword':'react','name':'react','type':'Search term'}],'timeRanges':['Past 12 months'],'examples':[],'shareText':'Explore search interest for react by time, location and popularity on Google Trends','shouldShowMultiHeatMapMessage':false}";
    
            dynamic data = JsonConvert.DeserializeObject(json);
    
            foreach(var result in data.widgets)
            {    
                Console.WriteLine(result.token);
            }
        }
    }
    

    Output:

    APP6_UEAAAAAXSXKDwW-kwcTrkXhBuCj17xOewtWmROU
    APP6_UEAAAAAXSXKD-rIwyhC21Abw8P2nPfb7AGhxrZ1
    APP6_UEAAAAAXSXKD9wlRrdtpbUyYXxko216LXZt21ra
    APP6_UEAAAAAXSXKD10s1DrnqESw00VH8rfqAEq4ZjmA
    

    You would need to take care of the extra characters that are before the actual JSON string in the text file in order for this to work correctly.