How to retrieve images from Facebook Graph API in android - xamarin

I have retrieved json data from facebook graph api requesting GET from
https://graph.facebook.com/YOUR_PAGE_ID/albums?fields=name,photos{picture}&access_token=YOUR_ACCESS_TOKEN/
Json data is as follows:
{
"data": [
{
"name": "School Kids",
"photos": {
"data": [
{
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-0/s130x130/15267641_1789056354665765_6384898034258459703_n.jpg?oh=44daa7be0ac1878e769bc16df444bd0a&oe=58B29329",
"id": "1789056354665765"
},
{
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-0/s130x130/15356660_1789056361332431_834718824553815513_n.jpg?oh=69b3f1b1697808b87eed1e3053a67aaf&oe=58B735FB",
"id": "1789056361332431"
},
{
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-0/s130x130/15356635_1789056401332427_1231396155404307815_n.jpg?oh=3de32d320ac6762adc0dbf8b1ef64e0e&oe=58F69648",
"id": "1789056401332427"
},
{
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-0/s130x130/15380574_1789337074637693_1697389498501034556_n.jpg?oh=ddd57d119882b47172af689abde20cfb&oe=58F15477",
"id": "1789337074637693"
}
],
"paging": {
"cursors": {
"before": "MTc4OTA1NjM1NDY2NTc2NQZDZD",
"after": "MTc4OTMzNzA3NDYzNzY5MwZDZD"
}
}
},
"id": "1789056284665772"
},
{
"name": "Cover Photos",
"photos": {
"data": [
{
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-0/s130x130/14519945_1762073987364002_4539899568406717011_n.jpg?oh=fc8c02e9ced0839eea22d08859b964d0&oe=58BC80D4",
"id": "1762073987364002"
}
],
"paging": {
"cursors": {
"before": "MTc2MjA3Mzk4NzM2NDAwMgZDZD",
"after": "MTc2MjA3Mzk4NzM2NDAwMgZDZD"
}
}
},
"id": "1762074137363987"
},
{
"name": "Profile Pictures",
"photos": {
"data": [
{
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-0/p130x130/14495327_1762072887364112_1611299743258720903_n.jpg?oh=ae87944069fd154e817468a38d9cb4a1&oe=58AE8D02",
"id": "1762072887364112"
}
],
"paging": {
"cursors": {
"before": "MTc2MjA3Mjg4NzM2NDExMgZDZD",
"after": "MTc2MjA3Mjg4NzM2NDExMgZDZD"
}
}
},
"id": "1762072884030779"
}
],
"paging": {
"cursors": {
"before": "MTc4OTA1NjI4NDY2NTc3MgZDZD",
"after": "MTc2MjA3Mjg4NDAzMDc3OQZDZD"
}
}
}
What I want from these data is to get image and album name and display in GridView in android.
My attempt parsing these data is as json object from this method
public async void downloadJsonFeedAsync(string url) {
var httpClient = new HttpClient();
Task < string > contentsTask = httpClient.GetStringAsync(url);
// await! control returns to the caller and the task continues to run on another thread
string content = await contentsTask;
Console.Out.WriteLine("Response Body: \r\n {0}", content);
//Convert string to JSON object
mObject = Newtonsoft.Json.JsonConvert.DeserializeObject < ImageGridItemRootObject > (content);
//Update listview
Activity.RunOnUiThread(() => {
mGridView.Adapter = new PhotoGalleryGridViewAdapter(this.Activity, Resource.Layout.PhotoGalleryGridItemView, mObject.data);
mProgressBar.Visibility = ViewStates.Gone;
});
}
// root object
public class ImageGridItemRootObject
{
public string name { get; set; }
public string photos { get; set; }
public List<ImageGridItem> data { get; set; }
}
//ImageGridItem
public class ImageGridItem
{
private string picture;
private string id;
public ImageGridItem():base()
{
}
public string Picture
{
get { return picture; }
set { picture = value; }
}
public string Id
{
get { return id; }
set { id = value; }
}
}
The problem is I get Picture Null. I wonder which is jSon Object and which is jSon Array so that I can format rootObject in-order to retrieve jSon Array .
Thank you in advance.

If you take the returned JSON and use Edit > Paste Special > Paste JSON as classes in Visual Studio you get the following classes:
public class Rootobject
{
public Datum[] data { get; set; }
public Paging paging { get; set; }
}
public class Paging
{
public Cursors cursors { get; set; }
}
public class Cursors
{
public string before { get; set; }
public string after { get; set; }
}
public class Datum
{
public string name { get; set; }
public Photos photos { get; set; }
public string id { get; set; }
}
public class Photos
{
public Datum1[] data { get; set; }
public Paging1 paging { get; set; }
}
public class Paging1
{
public Cursors1 cursors { get; set; }
}
public class Cursors1
{
public string before { get; set; }
public string after { get; set; }
}
public class Datum1
{
public string picture { get; set; }
public string id { get; set; }
}
It looks like your classes are not matching the JSON, which means the Deserializer does not know what to do with the key/values that do not match in your contract.
Adjust your classes to better match the classes above, and it will deserialize with the image urls.

Related

.NET Core : deserialization issue + how to get better insight into non-useful error text

I have the following JSON which I ran through a validator and 'Pasted JSON as classes' to build a model from the schema in Visual Studio:
{
"entity": {
"Successful Requests": [
{
"Status": 201,
"Resource ID": 34715818,
"Message": "Created resource 1 at URI: /rest/equipment/ids/34715818"
},
{
"Status": 201,
"Resource ID": 34715838,
"Message": "Created resource 2 at URI: /rest/equipment/ids/34715838"
}
],
"Failed Requests": [
{
"Status": 500,
"Resource ID": -1,
"Message": "Failed to create new resource 1. Bulk update failed. Cause: Template 'xxx' not found."
},
{
"Status": 500,
"Resource ID": -1,
"Message": "Failed to create new resource 2. Bulk update failed. Cause: Template 'xxx' not found."
}
]
},
"variant": {
"language": null,
"mediaType": {
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
},
"encoding": null,
"languageString": null
},
"annotations": [],
"mediaType": {
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
},
"language": null,
"encoding": null
}
This builds the following classes (I added the JsonProperties in the entity class because the property names contain spaces, I also tried without them and I get the same error):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace xxx.Data.Models
{
public class Rootobject
{
public Entity entity { get; set; }
public Variant variant { get; set; }
public object[] annotations { get; set; }
public Mediatype1 mediaType { get; set; }
public object language { get; set; }
public object encoding { get; set; }
}
public class Entity
{
[JsonProperty("Successful Requests")]
public SuccessfulRequest[] SuccessfulRequests { get; set; }
[JsonProperty("Failed Requests")]
public FailedRequest[] FailedRequests { get; set; }
}
public class SuccessfulRequest
{
public int Status { get; set; }
public int ResourceID { get; set; }
public string Message { get; set; }
}
public class FailedRequest
{
public int Status { get; set; }
public int ResourceID { get; set; }
public string Message { get; set; }
}
public class Variant
{
public object language { get; set; }
public Mediatype mediaType { get; set; }
public object encoding { get; set; }
public object languageString { get; set; }
}
public class Mediatype
{
public string type { get; set; }
public string subtype { get; set; }
public Parameters parameters { get; set; }
public bool wildcardType { get; set; }
public bool wildcardSubtype { get; set; }
}
public class Parameters
{
}
public class Mediatype1
{
public string type { get; set; }
public string subtype { get; set; }
public Parameters1 parameters { get; set; }
public bool wildcardType { get; set; }
public bool wildcardSubtype { get; set; }
}
public class Parameters1
{
}
}
I make an API call in code:
var response = await _repositorySvc.PutBulkEquipment(requestBody, Guid.NewGuid());
var result = response.Content.ReadAsStringAsync().Result;
_logger.LogWarning("------------------Result:");
_logger.LogWarning(result);
Which returns the following JSON string in the console:
{
"entity": "{\"Successful Requests\":[{\"Status\":201,\"Resource ID\":34715872,\"Message\":\"Created resource 1 at URI: /rest/equipment/ids/34715872\"},{\"Status\":201,\"Resource ID\":34715892,\"Message\":\"Created resource 2 at URI: /rest/equipment/ids/34715892\"}],\"Failed Requests\":[]}",
"variant": {
"language": null,
"mediaType": {
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
},
"encoding": null,
"languageString": null
},
"annotations": [],
"mediaType": {
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
},
"language": null,
"encoding": null
}
Then, when I attempt to deserialize the string to the Entity class:
var deserializedResponse = JsonConvert.DeserializeObject<Rootobject>(result);
I get the following error:
Error converting value
"{"Successful Requests":[{"Status":201,"Resource ID":34715872,"Message":"Created resource 1 at URI: /rest/equipment/ids/34715872"},{"Status":201,"Resource ID":34715892,"Message":"Created resource 2 at URI: /rest/equipment/ids/34715892"}],"Failed Requests":[]}"
to type 'xxx.Data.Models.Entity'.
Path 'entity', line 1, position 290.
Would anyone be able to spot any mistakes I'm making that I might be missing in the above scenario that could be contributing to me banging my head on a wall for the past day and a half on this? Everything looks correct to me and I'm stumped - I do a lot of deserialization and usually it's ez-mode so I'm not sure what I'm missing.
Is there any way to get better insight into deserialization issues in .NET Core?
Thank you!
If this is the JSON response:
"entity": "{\"Successful Requests\":[...],\"Failed Requests\":[]}",
then entity is of type string. Note the quotes in the beginning and the end. Also note that all the inner quotes are escaped using backslashes.
And the error message says exactly that, it cannot convert that string into an object. it did expect something more like
"entity": {"Successful Requests":[...], "Failed Requests":[]},

GraphQL dotnet Client response not deserializing

When deserializing into a dynamic I can get a response but when I try to deserialize into a typed object I get nothing back.
Types being serialized
public class User {
public string Forename { get; set; }
}
public class UserCollectionResponseType {
public List<User> Items { get; set; }
}
Request being made:
var response = await graphQLHttpClient.SendQueryAsync<UserCollectionResponseType >(this.request).ConfigureAwait(false);
Sample response from API
{
"data": {
"users": {
"items": [
{
"forename": "4212hotp0i"
},
{
"forename": "XO - Test"
},
{
"forename": "5422q5htsd"
},
{
"forename": "XR - Test"
},
{
"forename": "2035snyyex"
},
{
"forename": "2379plsmri"
},
{
"forename": "7100e1igjl"
},
{
"forename": "94 - Test"
},
{
"forename": "ZX - Test"
},
{
"forename": "Test"
}
]
}
}
}
I was missing the Data part of the Json when trying to deserialize into an object.
My final objects looked like this:
public partial class Data {
[JsonProperty("users")]
public Users Users { get; set; }
}
public partial class Users {
[JsonProperty("items")]
public Item[] Items { get; set; }
}
public partial class Item {
[JsonProperty("forename")]
public string Forename { get; set; }
}

How to serialize type information using custom serializer also for sub documents using NEST and Elasticsearch

I'm using the example on https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/custom-serialization.html#_serializing_type_information to get $type information for the documents in elasticsearch.
However as mentioned on the page this only returns type information for the outer document:
the type information is serialized for the outer MyDocument instance, but not for each MySubDocument instance in the SubDocuments collection.
So my question now is if anyone knows how to also get type information for sub documents?
I've tried using the same JsonSerializerSettings as in their example separate from Elasticsearch (using LinqPad) and there I get type information also for sub documents:
void Main()
{
var temp = new ListBlock
{
Id = 1,
Title = "Titel",
Blocks = new List<BlockContent> {
new InnerBlock {
Id = 11,
MyProperty ="Inner Property"
},
new InnerBlock2 {
Id = 12,
MyProperty2 = "Inner property 2"
}
}
};
var serializeOptions = new Newtonsoft.Json.JsonSerializerSettings
{
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
TypeNameAssemblyFormatHandling = Newtonsoft.Json.TypeNameAssemblyFormatHandling.Simple,
Formatting = Newtonsoft.Json.Formatting.Indented
};
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(temp, serializeOptions);
serialized.Dump();
}
public class BlockContent
{
public int Id { get; set; }
}
public class ListBlock : BlockContent
{
public string Title { get; set; }
public List<BlockContent> Blocks { get; set; }
}
public class ListBlock2 : BlockContent
{
public string Title2 { get; set; }
public List<BlockContent> Blocks { get; set; }
}
public class InnerBlock : BlockContent
{
public string MyProperty { get; set; }
}
public class InnerBlock2 : BlockContent
{
public string MyProperty2 { get; set; }
}
This code results in the following json:
{
"$type": "UserQuery+ListBlock, LINQPadQuery",
"Title": "Titel",
"Blocks": {
"$type": "System.Collections.Generic.List`1[[UserQuery+BlockContent, LINQPadQuery]], System.Private.CoreLib",
"$values": [
{
"$type": "UserQuery+InnerBlock, LINQPadQuery",
"MyProperty": "Inner Property",
"Id": 11
},
{
"$type": "UserQuery+InnerBlock2, LINQPadQuery",
"MyProperty2": "Inner property 2",
"Id": 12
}
]
},
"Id": 1
}
Using these versions at the moment:
Elasticsearch 7.4.2
Nest 7.4.2
Update:
The solution provided by Russ Cam below works like a charm for the data model included in the response, however I've put together an example below based on how we create indices (using automap) and bulk index the initial list of documents. This works fine if we exclude the list of Guids (CategoryIds) in the model but if we include it the following exception is thrown:
{
"took": 8,
"errors": true,
"items": [{
"index": {
"_index": "testindex",
"_type": "_doc",
"_id": "1",
"status": 400,
"error": {
"type": "mapper_parsing_exception",
"reason": "failed to parse field [categoryIds] of type [keyword] in document with id '1'. Preview of field's value: '{$values=[], $type=System.Collections.Generic.List`1[[System.Guid, System.Private.CoreLib]], System.Private.CoreLib}'",
"caused_by": {
"type": "illegal_state_exception",
"reason": "Can't get text on a START_OBJECT at 1:140"
}
}
}
}, {
"index": {
"_index": "testindex",
"_type": "_doc",
"_id": "2",
"status": 400,
"error": {
"type": "mapper_parsing_exception",
"reason": "failed to parse field [categoryIds] of type [keyword] in document with id '2'. Preview of field's value: '{$values=[], $type=System.Collections.Generic.List`1[[System.Guid, System.Private.CoreLib]], System.Private.CoreLib}'",
"caused_by": {
"type": "illegal_state_exception",
"reason": "Can't get text on a START_OBJECT at 1:141"
}
}
}
}
]
}
Here is a simple (.Net 5) console application where this behaviour hopefully can be reproduced by others also:
using System;
using System.Collections.Generic;
using System.Linq;
using Elasticsearch.Net;
using Nest;
using Nest.JsonNetSerializer;
using Newtonsoft.Json;
namespace ElasticsearchTypeSerializer
{
internal class Program
{
private const string IndexName = "testindex";
private static void Main(string[] args)
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool,
(builtin, settings) => new MySecondCustomJsonNetSerializer(builtin, settings));
settings.DisableDirectStreaming();
var client = new ElasticClient(settings);
CreateIndex(client);
IndexDocuments(client);
var documents = GetDocuments(client);
}
private static void CreateIndex(IElasticClient client)
{
var createIndexResponse = client.Indices.Create(IndexName, x => x.Map<MyDocument>(m => m.AutoMap()));
}
private static void IndexDocuments(IElasticClient client)
{
var documents = new List<MyDocument>
{
new()
{
Id = 1,
Name = "My first document",
OwnerId = 2,
SubDocuments = new List<SubDocument>
{
new MySubDocument {Id = 11, Name = "my first sub document"},
new MySubDocument2 {Id = 12, Description = "my second sub document"}
}
},
new()
{
Id = 2,
Name = "My second document",
OwnerId = 3,
SubDocuments = new List<SubDocument>
{
new MySubDocument {Id = 21, Name = "My third sub document"}
}
}
};
var bulkIndexResponse = client.Bulk(b => b.Index(IndexName).IndexMany(documents).Refresh(Refresh.True));
}
private static IEnumerable<MyDocument> GetDocuments(IElasticClient client)
{
var searchResponse = client.Search<MyDocument>(s => s.Index(IndexName).Query(q => q.MatchAll()));
var documents = searchResponse.Documents.ToList();
return documents;
}
}
public class MyDocument
{
public int Id { get; set; }
public string Name { get; set; }
public string FilePath { get; set; }
public int OwnerId { get; set; }
public List<Guid> CategoryIds { get; set; } = new();
public List<SubDocument> SubDocuments { get; set; }
}
public class SubDocument
{
public int Id { get; set; }
}
public class MySubDocument : SubDocument
{
public string Name { get; set; }
}
public class MySubDocument2 : SubDocument
{
public string Description { get; set; }
}
public class MySecondCustomJsonNetSerializer : ConnectionSettingsAwareSerializerBase
{
public MySecondCustomJsonNetSerializer(IElasticsearchSerializer builtinSerializer,
IConnectionSettingsValues connectionSettings)
: base(builtinSerializer, connectionSettings)
{
}
protected override JsonSerializerSettings CreateJsonSerializerSettings()
{
return new()
{
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Ignore,
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
};
}
}
}
Any help regarding this issue is very much appreciated!
If you want type information to be included for typed collections on a document, the derived contract resolver can be omitted, which supresses the type handling for collection item types
private static void Main()
{
var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
var settings = new ConnectionSettings(pool,
(builtin, settings) => new MySecondCustomJsonNetSerializer(builtin, settings));
var client = new ElasticClient(settings);
var document = new MyDocument
{
Id = 1,
Name = "My first document",
OwnerId = 2,
SubDocuments = new[]
{
new MySubDocument { Name = "my first sub document" },
new MySubDocument { Name = "my second sub document" },
}
};
var indexResponse = client.IndexDocument(document);
}
public class MyDocument
{
public int Id { get; set; }
public string Name { get; set; }
public string FilePath { get; set; }
public int OwnerId { get; set; }
public IEnumerable<MySubDocument> SubDocuments { get; set; }
}
public class MySubDocument
{
public string Name { get; set; }
}
public class MySecondCustomJsonNetSerializer : ConnectionSettingsAwareSerializerBase
{
public MySecondCustomJsonNetSerializer(IElasticsearchSerializer builtinSerializer, IConnectionSettingsValues connectionSettings)
: base(builtinSerializer, connectionSettings) { }
protected override JsonSerializerSettings CreateJsonSerializerSettings() =>
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Ignore,
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
};
}

file.filename is returned null in NEST elastic search query

I want to search on content field and return content and file name. The query below is taken from NEST github page
Connection string:
var node = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(node);
var client = new ElasticClient(settings);
My class:
The class of search type is below (I feel problem might be here):
public class myclass
{
public string Content { get; set; }
public string filename { get; set; }
}
So I need only content and filename which is in file.filename, but in my search it return null for file.filename but content do return in same query.
NEST API CALL:
var request = new SearchRequest
{
From = 0,
Size = 10,
Query = new TermQuery { Name="Web", Field = "content", Value = "findthis" }
};
var response = client.Search<myclass>(request);
var twet = response.Documents.Select(t=>t.Content).ToList();
As I am new to elastic search so can't understand it. I even don't know why I am using term query to search a document while in kibana I user different queries and quite understandable match and match_phrase queries. So please help me get file.filename.
Edit: I have tried to include this too (later removed):
Source = new SourceFilter { Includes = ("file.filename") }
KIBANA Call:
This is the call from kibana console:
GET /extract/_search
{
"from" : 0, "size" : 1
, "query": {
"match": {
"content": "findthis"
}
}
}
The call returns following result I have used 1 result to show here:
Document in Elastic Search Index:
{
"took": 322,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3330,
"max_score": 4.693223,
"hits": [
{
"_index": "extract",
"_type": "doc",
"_id": "29ebfd23bd7b276d7f3afc2bfad146d",
"_score": 4.693223,
"_source": {
"content": """
my title
A looooong document text to findthis.
""",
"meta": {
"title": "my title",
"raw": {
"X-Parsed-By": "org.apache.tika.parser.DefaultParser",
"Originator": "Microsoft Word 11",
"dc:title": "my title",
"Content-Encoding": "windows-1252",
"Content-Type-Hint": "text/html; charset=windows-1252",
"resourceName": "filename.htm",
"ProgId": "Word.Document",
"title": "my title",
"Content-Type": "text/html; charset=windows-1252",
"Generator": "Microsoft Word 11"
}
},
"file": {
"extension": "htm",
"content_type": "text/html; charset=windows-1252",
"last_modified": "2015-10-27T15:44:07.093+0000",
"indexing_date": "2018-02-10T08:16:23.329+0000",
"filesize": 32048,
"filename": "filename.htm",
"url": """file://D:\tmp\path\to\filename.htm"""
},
"path": {
"root": "e1a38f7da342f641e3eefad1ed1ca0f2",
"virtual": "/path/to/filename.htm",
"real": """D:\tmp\path\to\filename.htm"""
}
}
}
]
}
}
I am using NEST Api to get document file.filename from elastic search 6 on same server.
ISSUE:
Even though I have mentioned above too. Problem is filename is returned null in NEST API while content does return.
SOLUTION 1:
Using settings.DisableDirectStreaming(); I retrieved JSON result and created Following Class:
New Class:
public class Rootobject
{
public int took { get; set; }
public bool timed_out { get; set; }
public _Shards _shards { get; set; }
public Hits hits { get; set; }
}
public class _Shards
{
public int total { get; set; }
public int successful { get; set; }
public int skipped { get; set; }
public int failed { get; set; }
}
public class Hits
{
public int total { get; set; }
public float max_score { get; set; }
public Hit[] hits { get; set; }
}
public class Hit
{
public string _index { get; set; }
public string _type { get; set; }
public string _id { get; set; }
public float _score { get; set; }
public _Source _source { get; set; }
}
public class _Source
{
public string content { get; set; }
public Meta meta { get; set; }
public File file { get; set; }
public Path path { get; set; }
}
public class Meta
{
public string title { get; set; }
public Raw raw { get; set; }
}
public class Raw
{
public string XParsedBy { get; set; }
public string Originator { get; set; }
public string dctitle { get; set; }
public string ContentEncoding { get; set; }
public string ContentTypeHint { get; set; }
public string resourceName { get; set; }
public string ProgId { get; set; }
public string title { get; set; }
public string ContentType { get; set; }
public string Generator { get; set; }
}
public class File
{
public string extension { get; set; }
public string content_type { get; set; }
public DateTime last_modified { get; set; }
public DateTime indexing_date { get; set; }
public int filesize { get; set; }
public string filename { get; set; }
public string url { get; set; }
}
public class Path
{
public string root { get; set; }
public string _virtual { get; set; }
public string real { get; set; }
}
Query:
Instead of TermQuery I used MatchQuery here is my query, connection string is as above:
var request = new SearchRequest
{
From = 0,
Size = 1,
Query = new MatchQuery { Field = "content", Query = txtsearch.Text }
};
New Problem:
I tried much, though response does contain whole JSON result, but it is not being mapped properly.
I tried using Rootobject, Hits and Hit class but results only returned for _source as:
var response = client.Search<_Source>(request);
var twet = response.Documents.Select(t => t.file.filename).ToList();
Now I can retrieve content and file name but if I try using previous classes. The Hits and hits.total are returned as null.
I tried following queries:
var twet = response.Documents.SelectMany(t => t.hits.hits.Select(k => k._source.content)).ToList();
and
var twet1 = response.Hits.SelectMany(t => t.Source.hits.hits.Select(k => k._source.content)).ToList();
and
var twet1 = response.Documents.Select(t => t.Filename.fileName).ToList();
and
var twet = response.HitsMetadata.Hits.Select(t => t.Source.filename).ToList();
using Rootobject , Hits, Hit classes. While response does contain it.
So how can I use Rootobject class instead so that I can get whatever I want.
The elastic search server returns response as a JSON string and then Nest deserializes it into your required class.
In your case filename is a nested property inside the file property. To deserialize nested JSON properties check this link How to access nested object from JSON with Json.NET in C#
public class MyClass
{
public string Content { get; set; }
public FileClass File { get; set; }
}
public class Fileclass
{
public string Filename { get; set; }
}
And then you can read filename like response.Documents.Select(t=>t.File.Filename).ToList();

Xamarin C#: How can I get JSON loaded into a TableView?

I've been able to figure out how to call my web server, load JSON, loop through it and output values. But how can I populate this data into a cell. For example, I would like to output the 3 years returned into a table. How would I go about doing that?
async Task GetTowInfo()
{
loadingIndicator.StartAnimating ();
HttpClient client = new HttpClient ();
HttpResponseMessage response = await client.GetAsync ("myurl.com");
HttpContent content = response.Content;
var result = await content.ReadAsStringAsync ();
try
{
var parsed = JsonConvert.DeserializeObject<RootObject>(result);
foreach (var year in parsed.DATA.YEARMFG)
{
Console.WriteLine("Year: {0}", year);
}
}
catch (Exception e) {
Console.WriteLine (e);
}
loadingIndicator.StopAnimating ();
}
public class DATA
{
public List<int> YEARMFG { get; set; }
public List<string> MAKE { get; set; }
public List<string> MODEL { get; set; }
public List<string> ENGINE { get; set; }
public List<int> TOWLIMIT { get; set; }
public List<string> NOTE1 { get; set; }
public List<string> NOTE2 { get; set; }
}
public class RootObject
{
public int ROWCOUNT { get; set; }
public List<string> COLUMNS { get; set; }
public DATA DATA { get; set; }
}
<!----JSON------>
{
"ROWCOUNT": 3,
"COLUMNS": [
"YEARMFG",
"MAKE",
"MODEL",
"ENGINE",
"TOWLIMIT",
"NOTE1",
"NOTE2"
],
"DATA": {
"YEARMFG": [
2012,
2012,
2012
],
"MAKE": [
"Chevrolet/GMC",
"Chevrolet/GMC",
"Chevrolet/GMC"
],
"MODEL": [
"Avalanche 1500 4WD",
"Avalanche 1500 4WD",
"Avalanche 1500 4WD"
],
"ENGINE": [
"5.3L V-8",
"5.3L V-8",
"5.3L V-8"
],
"TOWLIMIT": [
5000,
5500,
8000
],
"NOTE1": [
"3.08 axle ratio",
"3.42 axle ratio",
"3.42 axle ratio"
],
"NOTE2": [
"",
"",
"Cooling or other accessory package required "
]
}
}

Resources