xamarin.forms - Newtonsoft.Json.JsonSerializationException: Error converting value - c#

I'm new to Xamarin.Forms. I`m trying to deserialize JSON string to display to into a listview. I succeeded to get the JSON string from the server but when trying to deserialize it, it throws this error:
Newtonsoft.Json.JsonSerializationException: Error converting value "El Rey Cantina TRC" to type 'App7.Page1+Place[]'. Path 'titulo', line 1, position 30.
Here is my code:
namespace App7
{
public partial class Page1 : ContentPage
{
static ListView lstPlaces = new ListView();
public Page1()
{
//borrar
Button newButn = new Button()
{
Text = "Connect to Service",
TextColor = Color.FromHex("#333333"),
HorizontalOptions = LayoutOptions.Center
};
Content = new StackLayout
{
Children = {
newButn,
lstPlaces
}
};
//borrar
//click
newButn.Clicked += newButn_Clicked;
lstPlaces.ItemTemplate = new DataTemplate(typeof(TextCell));
lstPlaces.ItemTemplate.SetBinding(TextCell.TextProperty, "titulo");
//click
}
async void newButn_Clicked(object sender, EventArgs e)
{
//que pedo
GeoNamesWebService geoService = new GeoNamesWebService();
Place[] places = await geoService.GetPlacesAsync();
lstPlaces.ItemsSource = places;
}
public class GeoNamesWebService
{
public GeoNamesWebService()
{
}
public async Task<Place[]> GetPlacesAsync()
{
var client = new System.Net.Http.HttpClient();
client.BaseAddress = new Uri("http://www.catcherapp.net/");
StringContent str = new StringContent("postalcode=752020&country=IN&username=nirmalh", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync(new Uri("http://www.catcherapp.net/borrar/borrar.php"), str);
var placesJson = response.Content.ReadAsStringAsync().Result;
Placeobject placeobject = new Placeobject();
if (placesJson != "")
{
placeobject = JsonConvert.DeserializeObject<Placeobject>(placesJson);
}
return placeobject.places;
}
}
public class Placeobject
{
[JsonProperty("titulo")]
public Place[] places { get; set; }
}
public class Place
{
public string placeName { get; set; }
}
}
}
The json string:
{"titulo":"Bistro Garden","idE":"gb54ezpjs9k0es8w5q","pp":"sge39na6rbpp7uudgk.jpg","direccion":"Feliciano Cobian #570, Col. Nueva Los Angeles, Torre\u00f3n","contador":null}
Any idea of what am I doing wrong?

Your JSON property "titulo" is a string not an array of Place. The json object would need to be:
{
"titulo":[
{"placeName":"place1"},
{"placeName":"place2"}]
}

Related

Send post data to api in C#

I have this api in php that works ok when sending data from an html form.
<?php
include_once 'apiAppMovil.php';
$api = new AppMovil();
$error = '';
if(isset($_POST["nombre"]) && isset($_POST["ape"]) && isset($_POST["email"]) && isset($_POST["pass"])){
if($api->subirImagen($_FILES['foto'])){
$item = array(
"nombre" => $_POST["nombre"],
"ape" => $_POST["ape"],
"email" => $_POST["email"],
"pass" => $_POST["pass"],
"foto" => $api->getImagen() //Not used
);
$api->add($item);
}else{
$api->error('Error con el archivo: ' . $api->getError());
}
}
else{
$api->error('Error al llamar a la API');
}
?>
I want to send data but from c#. My class is the following:
public partial class Root
{
[JsonProperty("items")]
public Item[] Items { get; set; }
}
public partial class Item
{/*
[JsonProperty("id")]
[JsonConverter(typeof(ParseStringConverter))]
public long Id { get; set; }*/
[JsonProperty("nombre")]
public string Nombre { get; set; }
[JsonProperty("ape")]
public string Ape { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("pass")]
public string Pass { get; set; }
[JsonProperty("foto")] //Not Used
public string Foto { get; set; }
}
and my method is:
private async Task SignUpApiPost()
{
var data = new Item
{
Nombre = "Eric",
Ape = "Pino",
Pass = "M2022",
Email = "ericpinodiaz#gmail.com",
Foto = "default.jpeg" //Not Used
};
// Serialize our concrete class into a JSON String
var json = JsonConvert.SerializeObject(data);
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
var httpClient = new HttpClient();
// Do the actual request and await the response
var response = await httpClient.PostAsync("https://app.domainexample.com/rest/add.php", httpContent);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//do thing
}
}
But I can't get the data to arrive, I have the errors "Error al llamar a la API" from Api php.
I think the problem is that var data = new Item{ is not declared correctly, can you help me and tell me where I am going wrong?
Thank you.
Edit:
I add the html with which it works correctly:
You should try something like the one below.
client.BaseAddress = new Uri("your url");
//HTTP POST
var postTask = client.PostAsJsonAsync<StudentViewModel>("your parameter name", Item);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
//do something
}

Cannot deserialize the current JSON object into type 'System.Collections.Generic.List1' in Xamarin Forms

I'm having an error in Xamarin Forms I tried to deserialize the object does anyone know What did I do wrong here?
This is my method
private async void GetEmployee()
{
var _token = await GetAccessToken();
//List<D365Employee> Employee = null;
using (var _clientD365 = new HttpClient())
{
var _uri = "domain here";
_client.BaseAddress = new Uri(_uri);
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
var _response = await _clientD365.GetAsync("my endpoint here");
var Emp = JsonConvert.DeserializeObject<List<Employee>>(_response.Content.ReadAsStringAsync().Result);
Employee = new ObservableCollection<Employee>(Emp);
}
}
This is my Model
public class Employee
{
[JsonProperty("#odata.etag")]
public string Context { get; set; }
public IList<EmployeeDetails> Value { get; set; }
}
public class EmployeeDetails
{
public string PersonnelNumber { get; set; }
public string EmploymentLegalEntityId { get; set; }
public string DimensionDisplayValue { get; set; }
}
This is the JSON I try to parse
{
"#odata.context": "https://employee.dynamics.com/data/$metadata#Employees(PersonnelNumber,EmploymentLegalEntityId,DimensionDisplayValue)",
"value": [
{
"#odata.etag": "W/\"JzEsNTYzNzE0NDYwMzsxNDg2NTk2NzY0LDU2MzcxNDc2OTM7MSw1NjM3MTQ0NjAzOzEsNTYzNzE0NDYwMzsxLDU2MzcxNDczNzE7MCwwOzAsMDsyNTY0OTEwODksNTYzwJw==\"",
"PersonnelNumber": "ID111028",
"EmploymentLegalEntityId": "OOP",
"DimensionDisplayValue": "----",
}
]
}
That JSON is a single object, not a list, so you need to deserialize it as a single object.
var Emp = JsonConvert.DeserializeObject<Employee>(await _response.Content.ReadAsStringAsync());

Display Multiple JsonObject on Listview

I have a Json from the server as below:
{
"data": {
"komik_popular": {
"title": "Yei! Komik Awas Nyamuk Jahat jadi literasi terpopuler minggu ini lho!"
},
"buku_baru": {
"title": "Ada buku baru nih, Katalog Prasekolah"
}
},
}
I want to display the json on the listview, but I try Debug.Writeline("judul: " + highlight.Title) first
Code:
Highlight highlight = new Highlight();
string title = "";
string urlPath = link;
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonObject jsonData = jsonObject["data"].GetObject();
JsonObject bukuBObject = jsonData.ContainsKey("buku_baru") && jsonData["buku_baru"] != null ? jsonData["buku_baru"].GetObject() : JsonObject.Parse("");
try
{
title = bukuBObject["title"].GetString();
}
catch
{
}
JsonObject komikPObject = jsonData.ContainsKey("komik_popular") && jsonData["komik_popular"] != null ? jsonData["komik_popular"].GetObject() : JsonObject.Parse("");
try
{
title = komikPObject["title"].GetString();
}
catch
{
}
highlight.Title = title;
Debug.WriteLine("judul: " + highlight.Title);
}
Highlight.cs:
class Highlight
{
public string Title { get; set; }
}
I'm having a problem, when I try to debug only the title on "komik_popular" is displayed, I want all the data in "komik_popular" and "buku_baru" to be displayed. How to handle it?
private List<Highlight > HighlightList = new List<Highlight>();
string urlPath = link;
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonObject jsonData = jsonObject["data"].GetObject();
JsonObject komikPObject = jsonData.ContainsKey("komik_popular") && jsonData["komik_popular"] != null ? jsonData["komik_popular"].GetObject() : JsonObject.Parse("");
try
{
Highlight highlight = new Highlight();
string title = "";
title = komikPObject["title"].GetString();
HighlightList.Add(highlight);
}
catch
{
}
JsonObject bukuBObject = jsonData.ContainsKey("buku_baru") && jsonData["buku_baru"] != null ? jsonData["buku_baru"].GetObject() : JsonObject.Parse("");
try
{
Highlight highlight = new Highlight();
string title = "";
title = bukuBObject["title"].GetString();
HighlightList.Add(highlight);
}
catch
{
}
}
catch
{
}
foreach( Highlight items in HighlightList)
{
Debug.WriteLine("judul: " + items .Title);
}
}
for converting json data to list, first you have to create respective class model as per given data format after that you can convert or deserialize it in your list format , in cae of your json data you can follow below example :-
public class Titel
{
public string title { get; set; }
}
public class Data
{
public Titel komik_popular { get; set; }
public Titel buku_baru { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
class Program
{
static void Main(string[] args)
{
string s = "{'data':{'komik_popular':{'title':'Yei! Komik Awas Nyamuk Jahat jadi literasi terpopuler minggu ini lho!'},'buku_baru':{'title':'Ada buku baru nih, Katalog Prasekolah'}}}";
List<RootObject> dataList = JsonConvert.DeserializeObject<List<RootObject>>(s);
}
}

C# JSON - Error: Cannot initialize type with collection initializer (does not implement 'System.Collection.IEnumerable')

I have problem debug the below (in the simplest way possible...). I have a set of properties for a JSON, everything works up to the point that I try to serialize. I would appreciate the simplest way possible to correct, I have to use Newtonsoft.
Below the full C# code. The error area is being marked in comments.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace MY_TEST
{
public partial class headers
{
[JsonProperty("RequestID")]
public string myRequest { get; set; } = "someIDhere";
[JsonProperty("CorrelationID")]
public string CorrelationID { get; set; } = "1234567890";
[JsonProperty("Token")]
public string Token { get; set; } = "areallylongstringgoeshereastoken";
[JsonProperty("ContentType")]
public string Content_Type { get; set; } = "application/x-www-form-urlencoded";
}
public partial class access
{
[JsonProperty("allPs")]
public string allPs { get; set; } = "all";
[JsonProperty("availableAccounts")]
public string availableAccounts { get; set; } = "all";
}
public partial class body
{
[JsonProperty("combinedServiceIndicator")]
public bool combinedServiceIndicator { get; set; } = false;
[JsonProperty("frequencyPerDay")]
public int frequencyPerDay { get; set; } = 4;
[JsonProperty("recurringIndicator")]
public bool recurringIndicator { get; set; } = false;
[JsonProperty("validUntil")]
public string validUntil { get; set; } = "2020-12-31";
}
public class Consent //RootObject
{
[JsonProperty("headers")]
public headers headers { get; set; }
[JsonProperty("body")]
public body body { get; set; }
}
class Program
{
static HttpClient client = new HttpClient();
static void ShowConsent(Consent cust_some)
{
Console.WriteLine(cust_some.ToString());
}
static async Task<Uri> CreateConsentAsync(Consent cust_some)
{
HttpResponseMessage response = await client.PostAsJsonAsync("http://myurladdr:8001/me/and/you/api/", cust_some);
ShowConsent(cust_some);
response.EnsureSuccessStatusCode();
return response.Headers.Location;
}
static async Task<Consent> GetConsentAsync(string path)
{
Consent cust_some = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
cust_some = await response.Content.ReadAsAsync<Consent>();
}
return cust_some;
}
static void Main()
{
RunAsync().GetAwaiter().GetResult();
}
static async Task RunAsync()
{
client.BaseAddress = new Uri("http://myurladdr:8001/me/and/you/api/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
// >---------- ERROR: Cannot initialize type 'Consent' with a collection initializer because it does not implement 'System.Collection.IEnumerable' ----------<
Consent cust_some = new Consent
{
// Headers
cust_some.headers.myRequest = "someIDhere",
cust_some.headers.CorrelationID = "1234567890",
cust_some.headers.Token = "areallylongstringgoeshereastoken"
cust_some.headers.Content_Type = "application/x-www-form-urlencoded",
// Body
cust_some.body.access.allPs = "all",
cust_some.body.access.availableAccounts = "all",
cust_some.body.combinedServiceIndicator = false,
cust_some.body.frequencyPerDay = 4,
cust_some.body.recurringIndicator = false,
cust_some.body.validUntil = "2020-12-31"
};
// >---------- ERROR ----------<
string json = JsonConvert.SerializeObject(cust_some, Formatting.Indented);
Console.WriteLine(json.ToString());
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine(json);
var url = await CreateConsentAsync(cust_some);
Console.WriteLine($"Created at {url}");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
}
}
Your'e using the identifier names inside their own initializer. For example, your'e using cust_some inside Consent initializer. You need to remove them, like so:
Consent cust_some = new Consent
{
// Headers
headers = new headers
{
myRequest = "someIDhere",
CorrelationID = "1234567890",
Token = "areallylongstringgoeshereastoken"
Content_Type = "application/x-www-form-urlencoded"
}
// Body
body = new body
{
access = new access
{
allPs = "all",
availableAccounts = "all"
}
combinedServiceIndicator = false,
frequencyPerDay = 4,
recurringIndicator = false,
validUntil = "2020-12-31"
};
}
Also, please note that per Microsoft naming conventions, all identifiers except parameter names should be capitalized, so e.g. headers, body, access and so on, both class and property names, should become Headers, Body, Access. You can read about it here.
In partial class body, add first before all the properties that are needed, the below:
[JsonProperty("access")]
public access access { get; internal set; }
Now, [kudos to user ***HeyJude**** - thank you!] create
Consent cust_some = new Consent
{
headers = new headers
{
myRequest = "someIDhere",
Correlation_ID = "1234567890",
Token = "areallylongstringgoeshereastoken",
Content_Type = "application/json" //"application/json; charset=utf-8"
},
body = new body
{
access = new access //this is how to include access in body
{
allPs = "allAccounts",
availableAccounts = "allAccounts"
},
combinedServiceIndicator = false,
frequencyPerDay = 4,
recurringIndicator = false,
validUntil = "2020-12-31"
}
};

Parse XML file and populate object with values

After I send a request with the required parameters in the response I get the following XML:
<content>
<main>
<IMGURL>image url</IMGURL>
<IMGTEXT>Click Here</IMGTEXT>
<TITLE>image title</TITLE>
<IMGLINK>image link</IMGLINK>
</main>
</content>
and I also made the following two classes:
[Serializable]
public class content
{
private Main _main;
public content()
{
_main = new Main();
}
public Main Main
{
get { return _main; }
set { _main = value; }
}
}
[Serializable]
public class Main
{
public string IMGURL { get; set; }
public string IMGTEXT { get; set; }
public string TITLE { get; set; }
public string IMGLINK { get; set; }
}
While debugging I can see that in the response I get the wanted results. However I'm having troubles deserializing the XML and populating the object.
Call to the method:
public static class ImageDetails
{
private static string _url = ConfigurationManager.AppSettings["GetImageUrl"];
public static content GetImageDetails(string ua)
{
var contenta = new content();
_url += "&ua=" + ua;
try
{
WebRequest req = WebRequest.Create(_url);
var resp = req.GetResponse();
var stream = resp.GetResponseStream();
//var streamreader = new StreamReader(stream);
//var content = streamreader.ReadToEnd();
var xs = new XmlSerializer(typeof(content));
if (stream != null)
{
contenta = (content)xs.Deserialize(stream);
return contenta;
}
}
catch (Exception ex)
{
}
return new content();
}
}
The serializer is case-sensitive. You either need to rename the property content.Main to main or add the attribute [XmlElement("main")] to it.

Categories