How to read this JSON on Windows Phone? - c#

I have to read this JSON :
[
{"id":"2","code":"jne","name":"JNE"},
{"id":"5","code":"pcp","name":"PCP"},
{"id":"1","code":"pos","name":"Pos Indonesia"},
{"id":"6","code":"wahana","name":"Wahana"}
]
I have tried this :
[DataContract]
public class Ekspedisi
{
[DataMember]
public int id { get; set; }
[DataMember]
public String code { get; set; }
[DataMember]
public String name { get; set; }
}
and this:
public static Ekspedisi[] res;
string link5 = "http://www.ongkoskirim.com/api/0.2/?id=OAL66afd139a386fee6dc5a5597abd7daba&q=expedition"
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri(link5), UriKind.Absolute);
and this :
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
var ser = new DataContractJsonSerializer(typeof(Ekspedisi));
res = (Ekspedisi[])ser.ReadObject(e.Result);
for (int i = 0; i < length; i++)
{
Debug.WriteLine(res[i].id+","+res[i].name);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
}
}
But it always showing invalidCastException. Can anyone help me?

When you are deserialising the JSON, you are using the type of Ekspedisi even though you are returning a collection. If you change this line of code:
var ser = new DataContractJsonSerializer(typeof(Ekspedisi));
to
var ser = new DataContractJsonSerializer(typeof(IEnumerable<Ekspedisi>));
which is a collection of your type; you will find you no longer receive the exception.

Related

C#: "Cannot deserialize the current JSON array"

I would like to start by saying that I am not a developer and this is my very first time writing a code to this extend of complication (at least to me). Any help/guidance would be much appreciated.
The idea of this program is to retrieve the employee user ID (or signature) from an API URL once the name has been entered.
I created a class that identifies the information that needs to be retrieved from the API (Below is the code):
namespace TimeSheet_Try11_Models
{
public class Employeename
{
public List<string> Signature { get; set; }
public List<string> FirstName { get; set; }
public List<string> FullName { get; set; }
public List<string> LastName { get; set; }
}
}
Next I created a folder called WebAPI which will access the API and retrieve the needed information. (please see the code)
namespace TimeSheets_Try_11.Controllers
{
class WebAPI
{
public string Getsignature(string name)
{
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlIora), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.UseDefaultCredentials = true;
string uri = "";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
uri = StaticStrings.UrlIora + name;
var response = wc.DownloadString(uri);
string json = #"[{'signature':'JANDO','firstName':'Jane','fullName':'Deo, Jane','lastName':'Deo'}]";
Employeename status = JsonConvert.DeserializeObject<Employeename>(json);
string signature = status.Signature.ToString();
return signature;
}
}
}
Finally, the following code is my code for the forms that will retrieve and display information.
namespace TimeSheets_Try_11
{
public partial class Form1 : Form
{
WebAPI WA = new WebAPI();
public Form1()
{
InitializeComponent();
webBrowser1.Url = new Uri(StaticStrings.UrlIora);
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string strurltest = string.Format("https://iora.UniversityofHouston.com/api/dictionary/employee/" + textBox1.Text);
System.Net.WebRequest requestObjGet = WebRequest.Create(strurltest);
requestObjGet.Credentials = CredentialCache.DefaultNetworkCredentials;
requestObjGet.Method = "Get";
HttpWebResponse reponsObjGet = null;
reponsObjGet = (HttpWebResponse)requestObjGet.GetResponse();
string[] usernames = new string[] { "Koehne, Craig", "Bergeron, Ronald" };
string[] userid = new string[] { "CKOEH", "RONBE" };
for (int i = 0; i < usernames.Length; i++)
{
if (textBox1.Text.Contains(usernames[i]))
{
textBox2.Text = userid[i];
}
}
string sgname; string projectstring;
projectstring = textBox1.Text.ToString();
sgname = WA.Getsignature(projectstring);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
string StringConn = textBox1.Text;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
}
Problem: The code does not seem to have any errors, however when I start debugging the code, it gives me an error that states:
"Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array (e.g. [1,2,3]) into type
'TimeSheet_Try11_Models.Employeename' because the type requires a JSON
object (e.g. {"name":"value"}) to deserialize correctly."
Your JSON string contains an array that contains one object. But you're trying to deserialize it into just a single object.
Either deserialize the JSON string into a C# array:
string json = #"[{'signature':'JANDO','firstName':'Jane','fullName':'Deo, Jane','lastName':'Deo'}]";
Employeename[] status = JsonConvert.DeserializeObject<Employeename[]>(json);
Or change the JSON string so it's no longer an array, just an object:
string json = #"{'signature':'JANDO','firstName':'Jane','fullName':'Deo, Jane','lastName':'Deo'}";
Employeename status = JsonConvert.DeserializeObject<Employeename>(json);
Also, your Employeename class makes no sense, the properties should be of type string:
public class Employeename
{
public string Signature { get; set; }
public string FirstName { get; set; }
public string FullName { get; set; }
public string LastName { get; set; }
}

C# reference Error while setting value using GetType().GetTypeInfo().GetDeclaredProperty for existing Property [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have a relatively simple console app (framework) which has a tightly coupled classes with properties and my main triggers an async task. These are my property classes:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http; //for HTTP client
using System.Reflection;
using System.Threading.Tasks; //for Async Request/Response
using Newtonsoft.Json; //for JSON properties
namespace PSD2
{
[Serializable]
public class PS
{
public System.Uri BaseURL { get; set; } = new System.Uri("http://192.999.999.999:8888/some/url/here/");
public ConsHeaders Headers { get; set; }
public ConsBody Body { get; set; }
public consAttributes Attributes { get; set; }
}
[Serializable]
public partial class ConsHeaders
{
[JsonProperty("Core-ID")]
public string corID { get; set; }
[JsonProperty("PS-Token")]
public string PS_Token { get; set; }
[JsonProperty("Req-ID")]
public string reqID { get; set; }
}
[Serializable]
public partial class consAttributes
{
[JsonProperty("consId")]
public string consId { get; set; } = String.Empty;
[JsonProperty("consStatus")]
public string consStatus { get; set; } = String.Empty;
[JsonProperty("userName")]
public string userName { get; set; } = String.Empty;
};
[Serializable]
public partial class consBody
{
[JsonProperty("access")]
public AccessHeaders access { get; internal set; }
[JsonProperty("combinedServiceIndicator")]
public Boolean CombinedServiceIndicator { get; set; } = false;
[JsonProperty("frequencyPerDay")]
public int FrequencyPerDay { get; set; } = 4;
[JsonProperty("recurringIndicator")]
public Boolean RecurringIndicator { get; set; } = false;
[JsonProperty("validUntil")]
public string ValidUntil { get; set; } = "9999-12-31";
}
...
Now, my Program class creates an object and in Main I call a class called testing who has my logic behind, nothing more than populating the object properties with values, and calls a Task asycn which is also present inside. Code continues from above as:
public class Program
{
public static PS cnsnt = new PS();
public static void Main(string[] args)
{
Testing test = new Testing();
test.createCONS();
}
public class Testing
{
public void createCONS()
{
try
{
cnsnt.Headers = new ConsHeaders
{
corID = "Something",
reqID = "AnotherThing",
PS_Token = "myTokenValue"
};
cnsnt.Body = new ConsBody
{
access = new AccessHeaders
{
AllPsd2 = "allAccounts",
AvailableAccounts = "YES"
},
CombinedServiceIndicator = false,
FrequencyPerDay = 10,
ValidUntil = "2020-12-31"
};
cnsnt.Attributes = new consAttributes
{
consId = "",
_links_self_href = "",
consStatus = "",
status_href = "",
userName = ""
};
}
catch (System.Exception e)
{
throw new System.Exception("Error - Aborting..");
}
myConsAsync(cnsnt.BaseURL, cnsnt, HttpMethod.Post).GetAwaiter().GetResult();
}
public async static Task myConsAsync(Uri HTTPaddress, PS ConSent, HttpMethod httpMethod)
{
try
{
HttpClient client = new HttpClient();
System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
using (HttpRequestMessage request = new HttpRequestMessage(httpMethod, HTTPaddress))
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//...
client.DefaultRequestHeaders.Add("Core-ID", ConSent.Headers.corID);
client.DefaultRequestHeaders.Add("Req-ID", ConSent.Headers.reqID);
client.DefaultRequestHeaders.Add("PS-Token", ConSent.Headers.PS_Token);
//...
request.Content = new StringContent(JsonConvert.SerializeObject(ConSent, Formatting.Indented), utf8, "application/json");
using (HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
Int32 code = (Int32)response.StatusCode;
string responseBody = response.Content.ReadAsStringAsync().Result.ToString();
try
{
if (responseBody.Contains("consId"))
{
try
{
string responseValues = JSONtoKeyValue(responseBody);
var dict = responseValues.Split('|')
.Select(x => x.Split('='))
.Where(x => x.Length > 1
&& !String.IsNullOrEmpty(x[0].Trim())
&& !String.IsNullOrEmpty(x[1].Trim()))
.ToDictionary(x => x[0].Trim(), x => x[1].Trim());
foreach (KeyValuePair<string, string> entry in dict)
{
if (entry.Value == null)
{
dict.Remove(entry.Key);
}
else
{
string key = entry.Key;
string value = entry.Value;
try
{
if (cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
{
// ---> ERROR: Object reference not set to an instance of an object.
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
}
}
catch (System.Exception e)
{
Console.WriteLine("Failed during processing Property: " + e.Message);
}
}
}
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine(e.StackTrace + "\r\n" + e.Message);
}
}
else
{
throw new System.Exception("Fatal error reading response body for the consent Id. Aborting..");
};
}
catch (System.Exception e)
{
Environment.Exit(13);
}
}
}
}
catch (Exception e)
{
//whatever, Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message + "\r\n" + e.Data);
}
//return
}
// this works as intended.. included just for completion
public static string JSONtoKeyValue(string pString)
{
pString.Trim();
if (pString == null)
{
return "";
}
else
{
pString = pString.Replace("\r\n", "|").Replace(":", "=").Replace("\"", "").Replace("{", "").Replace("}", "").Replace(",", "");
int j = 0, inputlen = pString.Length;
char[] newarr = new char[inputlen];
for (int i = 0; i < inputlen; ++i)
{
char tmp = pString[i];
if (!char.IsWhiteSpace(tmp))
{
newarr[j] = tmp; ++j;
}
}
return new String(newarr, 0, j).Replace("||", "|").Replace("||", "|").Replace("=|", "_").Trim('|');
}
}
}
}
}
Notice in the Task that I want to read a string separated with pipes (a small method does the work nicely) and I try to see if I have this property in my object, and if yes, to populate the value.
However, in line
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
I get the error "Object reference not set to an instance of an object."
I struggle on this one, could someone help me?
You have made a simple mistake.
You check for
(cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
But then you assign with
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value)
Just replace it with,
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value).
Note its cnsnt. Not ConSent.
and you'll be fine. Happy reflecting!
edit:
saw your edit, same thing.
cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key)
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key)
you are basically checking on a different bject if it has a property and then you try to set it on another.
Suggestion.
Why not go:
var keyProperty = cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key);
if(keyProperty != null)
{
keyProperty.SetValue(cnsnt, entry.Value);
}
this way it will not fail, ever.

With RestSharp, Newtonsoft.Json Cannot deserialize the current JSON array (e.g. [1,2,3])

I am new to C# API... I created a new server using nodejs server get data from SQL server to generate json and I am creating a custom application using c# windows application using RestSharp sent a request to a server and received a response using Newtonsoft I got error cannot deserialize current json array help me to solve the problem below code
JSON
[[{"id":2000,"engine":1,"wheel":1,"ac":1,"nitro":1,"rim":1},{"id":2001,"engine":1,"wheel":1,"ac":1,"nitro":1,"rim":1}]]
Code
using RestSharp;
using Newtonsoft.Json;
private void Form1_Load(object sender, EventArgs e)
{
var client = new RestClient("http://localhost:8000/employees");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
var x = JsonConvert.DeserializeObject<RootObject>(response.Content);
foreach (var player in x.Abbrecipes)
{
comboBox1.Items.Add(player.id);
}
}
public class Abbrecipe
{
public int id { get; set; }
public int engine { get; set; }
public int wheel { get; set; }
public int ac { get; set; }
public int nitro { get; set; }
public int rim { get; set; }
}
public class RootObject
{
public List<Abbrecipe> Abbrecipes { get; set; }
}
here is the code for your current situation as a method using WebClient instead of RestClient:
private static Rootobject publicFeed;
public static void Set()
{
publicFeed = new Rootobject();
using (var client = new WebClient())
{
string result;
try
{
result = client.DownloadString("your json");//configure json stringdata
}
catch (Exception)
{
Console.WriteLine("This application needs a valid internet connection, please try again.");
result = null;
return;
}
publicFeed = JsonConvert.DeserializeObject<Rootobject>(result);
}
}

How to parse the Json data in windows phone 8

I am new to windows phone 8 development. I am working on application in which I need parse the Json. so I am not able to get the following data in windows phone 8.
{
"response":{
"errorFlag":0,
"Score Detail":{
"39":[
{
"test_date":"2013-06-28",
"total_marks":"50",
"score":"14"
},
{
"test_date":"2013-08-08",
"total_marks":"20",
"score":"20"
}
],
"40":[
{
"test_date":"2013-08-08",
"total_marks":"20",
"score":"20"
},
{
"test_date":"2013-08-08",
"total_marks":"30",
"score":"20"
},
{
"test_date":"2013-08-08",
"total_marks":"30",
"score":"20"
}
],
"50":[
{
"test_date":"2013-08-08",
"total_marks":"30",
"score":"20"
}
]
}
}
}
I am trying to parse the data in the following way
namespace testscore
{
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Mainpage_Loaded);
}
void Mainpage_Loaded(object sender, RoutedEventArgs e)
{
WebClient webClient1 = new WebClient();
webClient1.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient1_DownloadStringCompleted);
webClient1.DownloadStringAsync(new Uri("some link"));
}
public void webClient1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
MessageBox.Show(e.Result.ToString());
foreach (var res in rootObject.response.ScoreDetail)
{
string rs = res.Key;
MessageBox.Show(rs.ToString());
......
}
}
public class RootObject
{
public Response response { get; set; }
}
public class Response
{
public int errorFlag { get; set; }
[JsonProperty("Score Detail")]
public JObject ScoreDetail { get; set; }
}
Here I am to getting key value (here it is 39) but I am not able to get the values of the score, testdate and marks. please help me in parsing these details.
Thanks in advance.
I propose you to build classes of your json :
public class RootObject
{
public Response response { get; set; }
}
public class Response
{
public int errorFlag { get; set; }
[JsonProperty("Score Detail")]
public JObject ScoreDetail { get; set; }
}
You can use them on the DownloadStringCompleted event :
public void webClient1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
RootObject root = JsonConvert.DeserializeObject<RootObject>(e.Result);
JObject obj = root.response.ScoreDetail;
foreach (KeyValuePair<string, JToken> pair in obj)
{
string key = pair.Key; // here you got 39.
foreach (JObject detail in pair.Value as JArray)
{
string date = detail["test_date"].ToString();
string score = detail["score"].ToString();
string total_marks = detail["total_marks"].ToString();
}
}
}
Hope it helps !
var result= JObject.Parse(response)["response"]["ScoreDetail"];
foreach (var item in result)
{
// Code to store the result
}

Weird message getting with serialization and c#

I tried to send it from one client to another, and the source, destination and the data receive fine, but the string and the double become null. This is the code of the TcpObject:
[Serializable]
public class TcpObject
{
public Command Command { set; get; }
public Object Data { set; get; }
public int Source { set; get; }
public int Destination { set; get; }
public string IDString { set; get; }
public double exactTime { set; get; }
public TcpObject()
{
Command = Command.Null;
Data = null;
}
This is where I send the data:
TcpObject tcpObject = new TcpObject();
tcpObject.Command = Command.Msg;
tcpObject.Source = 1;
tcpObject.Destination = 2;
byte[] junkMsg = new byte[1000];
tcpObject.Data = junkMsg;
tcpObject.IDString = randomString();
tcpObject.exactTime = exactTime.ExactTime();
WorkClient.Send(tcpObject);
hread.Sleep(20);
And this is where I receive:
public void Listen()
{
try
{
while (Connected)
{
TcpObject tcpObject = new TcpObject();
IFormatter formatter = new BinaryFormatter();
tcpObject = (TcpObject)formatter.Deserialize(ServerSocket);
MessageBox.Show(tcpObject.IDString);
//TcpObject succeedTcpObject = new TcpObject();
//get the remainder of the time that the message got send and when the message got accepted.
}
}
catch (Exception) { }
}
This is the send function:
public static void Send(TcpObject tcpObject)
{
try
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(ServerSocket, tcpObject);
}
catch (Exception) { }
}
The MessageBox that pops up is empty. I checked before I sent the msg and the string was present.
Thanks.
Obviously, you send garbage that is never initialized:
byte[] junkMsg = new byte[1000];
tcpObject.Data = junkMsg;
--SNIP--
WorkClient.Send(tcpObject);

Categories

Resources