Newtonsoft JSON deserialize using HttpWebResponse - c#

I was searching in all the questions about deserialization with Newtonsfot Json Converter. But i wasn't able to find the problem in my code. So I put here, asking for help.
The message error from the visual studio:
No se controló Newtonsoft.Json.JsonSerializationException
HResult=-2146233088
Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'APIEffilogics.Usuari+Client' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array.
JsonArrayAttribute can also be added to the type to force it to
deserialize from a JSON array.
My JSON response is like this:
[ {
"id": 32,
"consultancy_id": 1,
"nif": "B61053922",
"contactname": "",
"email": "",
"phone": "",
"active": true,
"description": "Keylab" },
{
"id": 19,
"consultancy_id": 1,
"nif": "P0818300F",
"contactname": "Pau Lloret",
"email": "lloret#citcea.upc.edu",
"phone": "",
"active": true,
"description": "Rubi" } ]
And those are the classes:
namespace APIEffilogics
{
public class Usuari
{
public string access_token; //Encapsulat que conté la identificació de seguretat
public string token_type; //Tipus de token, "Bearer"
public string response; //Resposta de l'API
public class Client : Usuari //Estructura client
{
[JsonProperty("id")]
public string cid { get; set; }
[JsonProperty("consultancy_id")]
public string consultancy_id { get; set; }
[JsonProperty("contactname")]
public string contactname { get; set; }
[JsonProperty("email")]
public string email { get; set; }
[JsonProperty("description")]
public string description { get; set; }
[JsonProperty("nif")]
public string nif { get; set; }
[JsonProperty("phone")]
public string phone { get; set; }
[JsonProperty("active")]
public string active { get; set; }
}
public class Building : Usuari //Estructura edifici
{
public string descrip;
public string bid;
}
public class Floor : Usuari //Estructura planta
{
public string descrip;
public string fid;
}
public class Room : Usuari //Estructura habitació
{
public string descrip;
public string rid;
}
public class Node : Usuari //Estructura nodes
{
public string[] descrip;
public string[] nid;
public string[] model;
public string[] type;
}
}
//************************END PUBLIC CLASS Usuari***************************//
}
The code that I use:
public void Request(string url, string metode)
{
try
{
//Enviem la petició a la URL especificada i configurem el tipus de connexió
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.KeepAlive = true;
myReq.Headers.Set("Cache-Control", "no-store");
myReq.Headers.Set("Pragma", "no-cache");
myReq.Headers.Set("Authorization", usuari.token_type + " " + usuari.access_token);
if (metode.Equals("GET") || metode.Equals("POST"))
{
myReq.Method = metode; // Set the Method property of the request to POST or GET.
if (body == true)
{
// add request body with chat search filters
List<paramet> p = new List<paramet>();
paramet p1 = new paramet();
p1.value = "1";
string jsonBody = JsonConvert.SerializeObject(p1);
var requestBody = Encoding.UTF8.GetBytes(jsonBody);
myReq.ContentLength = requestBody.Length;
myReq.ContentType = "application/json";
using (var stream = myReq.GetRequestStream())
{
stream.Write(requestBody, 0, requestBody.Length);
}
body = false;
}
}
else throw new Exception("Invalid Method Type");
//Obtenim la resposta del servidor
HttpWebResponse myResponse = (HttpWebResponse)myReq.GetResponse();
Stream rebut = myResponse.GetResponseStream();
StreamReader readStream = new StreamReader(rebut, Encoding.UTF8); // Pipes the stream to a higher level stream reader with the required encoding format.
string info = readStream.ReadToEnd();
var jsondata = JsonConvert.DeserializeObject<Usuari.Client>(info);
myResponse.Close();
readStream.Close();*/
}
catch (WebException ex)
{
// same as normal response, get error response
var errorResponse = (HttpWebResponse)ex.Response;
string errorResponseJson;
var statusCode = errorResponse.StatusCode;
var errorIdFromHeader = errorResponse.GetResponseHeader("Error-Id");
using (var responseStream = new StreamReader(errorResponse.GetResponseStream()))
{
errorResponseJson = responseStream.ReadToEnd();
}
}
}
I don't know where is the problem, the response have the correct JSON scheme. Somebody can explain me where is the problem in my code, or if I'm not doing correctly.
I've solved the problem how you say, nut now I've a similar problem and the same message error. The JSON response now is this:
{
nodes: [
{
id: 5,
global_id: 5,
description: "Oven",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 2,
nodetype_id: 1
},
{
id: 39,
global_id: 39,
description: "Fridge",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 8,
nodetype_id: 1
}, ...
],
limit: 10,
offset: 0
}
And those are the classes:
public class Node : Usuari //Estructura nodes
{
[JsonProperty("limit")]
public int limit { get; set; }
[JsonProperty("offset")]
public int offset { get; set; }
[JsonProperty("nodes")]
public List<Node_sub> nodes_sub { get; set; }
}
public class Node_sub : Node
{
[JsonProperty("id")]
public string nid { get; set; }
[JsonProperty("global_id")]
public string gid { get; set; }
[JsonProperty("description")]
public string descrip { get; set; }
[JsonProperty("room_id")]
public string rid { get; set; }
[JsonProperty("floor_id")]
public string fid { get; set; }
[JsonProperty("client_id")]
public string cid { get; set; }
[JsonProperty("building_id")]
public string bid { get; set; }
[JsonProperty("nodemodel_id")]
public string model { get; set; }
[JsonProperty("nodetype_id")]
public string type { get; set; }
}
The code is the same as before, only I add this sentences:
jsonnode = JsonConvert.DeserializeObject<List<Usuari.Node>>(info);
Why I'm having the same error? List<Usuari.Node> is an array that contains all the items of JSON message.
Thanks

Try
var jsondata = JsonConvert.DeserializeObject<List<Usuari.Client>>(info);
This addresses the issue as the exception suggests:
To fix this error either change the JSON to a JSON object (e.g.
{"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array
Emphasis added to highlight the salient point
The HTTP response you receive is an array of objects so you need to deserialise it in a way that can deal with an array of objects. By changing your code to deserialise into a List<Usari.Client> you do just that and it should resolve the error.

Related

How to assign value to variable from a google API Json Response c#

I am trying to assign the value of a key from an async JSON response to a variable, the JSON key in question is the "threatType" Key. I am querying google's safebrowsing v4 API and I get a good response, the problem is when I try to assign a key to a variable nothing is assigned. Here's my code:
public static async Task<string> CheckUrl( string Api_Key, string MyUrl)
{
safeBrowsing_panel i = new safeBrowsing_panel();
var service = new SafebrowsingService(new BaseClientService.Initializer
{
ApplicationName = "Link-checker",
ApiKey = Api_Key
});
var request = service.ThreatMatches.Find(new FindThreatMatchesRequest()
{
Client = new ClientInfo
{
ClientId = "Link-checker",
ClientVersion = "1.5.2"
},
ThreatInfo = new ThreatInfo()
{
ThreatTypes = new List<string> { "SOCIAL_ENGINEERING", "MALWARE" },
PlatformTypes = new List<string> { "ANY_PLATFORM" },
ThreatEntryTypes = new List<string> { "URL" },
ThreatEntries = new List<ThreatEntry>
{
new ThreatEntry
{
Url = MyUrl
}
}
}
});
var response = await request.ExecuteAsync();
string json = JsonConvert.SerializeObject(await request.ExecuteAsync());
string jsonFormatted = JToken.Parse(json).ToString(Formatting.Indented);
Console.WriteLine(jsonFormatted);
return jsonFormatted;
}
I created classes to parse the json:
public class ThreatRes
{
public string threatType;
}
public class RootObjSB
{
public List<ThreatRes> matches;
}
And I call it with:
string SB_Result = await CheckUrl("MyAPIKey", "Bad_URL");
RootObjSB obj = JsonConvert.DeserializeObject<RootObjSB>(SB_Result);
The JSON response from google:
{
"matches": [
{
"cacheDuration": "300s",
"platformType": "ANY_PLATFORM",
"threat": {
"digest": null,
"hash": null,
"url": "http://badurl.com/",
"ETag": null
},
"threatEntryMetadata": null,
"threatEntryType": "URL",
"threatType": "SOCIAL_ENGINEERING",
"ETag": null
}
],
"ETag": null
}
I need help please.
So I tried using JavaScriptSerializer and it seemed to work just fine, I also reconstructed my classes to parse all the properties on the JSON response.
Reconstructed Classes:
public class Threat
{
public object digest { get; set; }
public object hash { get; set; }
public string url { get; set; }
public object ETag { get; set; }
}
public class Match
{
public string cacheDuration { get; set; }
public string platformType { get; set; }
public Threat threat { get; set; }
public object threatEntryMetadata { get; set; }
public string threatEntryType { get; set; }
public string threatType { get; set; }
public object ETag { get; set; }
}
public class RootObjSB
{
public List<Match> matches { get; set; }
public object ETag { get; set; }
}
and i deserialize it like this:
string SB_Result = await CheckUrl("MyAPIKey", "Bad_URL");
var obj = new JavaScriptSerializer().Deserialize<RootObjSB>(SB_Result);
string threat = obj.matches[0].threatType;
Console.WriteLine(threat);
I really don't know why the first option I tried didn't parse the data correctly but this was how I overcame that problem. Hope it helps anyone going through the same thing

Json deserialize is not working

I am receiving a Json response from an API but unable to convert to object.
My class is
public class ResultOrder
{
public int id { get; set; }
public string currency { get; set; }
public string status { get; set; }
public string order_id { get; set; }
public double price { get; set; }
}
var response = await client.PostAsync(path, body);
if (response.IsSuccessStatusCode)
{
var newOrder = await response.Content.ReadAsAsync<dynamic>();
ResultOrder obj = JsonConvert.DeserializeObject(newOrder);
}
And the result i am getting from API in the variable newOrder is --
{
"id": 68456,
"currency": "USD",
"status": "pending",
"price": "79.97",
"order_id": "1233219",
}
But unable to get the deserialized result in the obj variable.
You can just do
ResultOrder obj = response.Content.ReadAsAsync<ResultOrder>()
directly. This will handle the deserialisation for you.
Following changes you need to do to deserialize the newOrder object.
ResultOrder obj = JsonConvert.DeserializeObject<ResultOrder>(newOrder);
While deserializing the object, cast to desire object in your case it is ResultOrder

To convert address data in json to an address object

When making a request for an address web service, I get the following Json:
{
"cep": "04194-280",
"logradouro": "Rua Memorial de Aires",
"complemento": "",
"bairro": "Jardim São Savério",
"localidade": "São Paulo",
"uf": "SP",
"unidade": "",
"ibge": "3550308",
"gia": "1004"
}
I need to convert this json to the following object:
public class Endereco
{
[JsonProperty("cep")]
public string CEP { get; set; }
[JsonProperty("logradouro")]
public string Logradouro { get; set; }
[JsonProperty("complemento")]
public string Complemento { get; set; }
[JsonProperty("bairro")]
public string Bairro { get; set; }
[JsonProperty("localidade")]
public string Localidade { get; set; }
[JsonProperty("uf")]
public string UF { get; set; }
[JsonProperty("ibge")]
public string IBGE { get; set; }
[JsonProperty("unidade")]
public string Unidade { get; set; }
[JsonProperty("gia")]
public string GIA { get; set; }
}
The code that converts json to an object is as follows:
using (WebClient client = new WebClient())
{
string jsonAddress = JsonConvert.SerializeObject(client.DownloadString("http://viacep.com.br/ws/" + tboCep.Text + "/json/"));
Addressa ddr = JsonConvert.DeserializeObject<Endereco>(jsonAddress);
tboCidade.Text = address.Localidade; //City
tboEstado.Text = address.UF; // State
tboRua.Text = address.Logradouro; // Street
tboBairro.Text = address.Bairro; // District
}
But I always get the following error:
Error converting value "{
"cep": "04194-280",
"logradouro": "Rua Memorial de Aires",
"complemento": "",
"bairro": "Jardim São Savério",
"localidade": "São Paulo",
"uf": "SP",
"unidade": "",
"ibge": "3550308",
"gia": "1004"
}" to type 'ApiCorreios.Endereco'. Path '', line 1, position 269.
Would anyone know how to solve or have a better suggestion? Thank you in advance!
You are double serializing here.
string jsonAddress = JsonConvert.SerializeObject(client.DownloadString("http://viacep.com.br/ws/" + tboCep.Text + "/json/"));
the string returned from the client is already a serialized object and you are basically serializing it again.
Take the string returned directly from the web call and deseirlaize that
string jsonAddress = client.DownloadString("http://viacep.com.br/ws/" + tboCep.Text + "/json/");
var ddr = JsonConvert.DeserializeObject<Endereco>(jsonAddress);

C# and jSON is not working

Need a little help here
So I have a json url and need to get each item into a for each loop
Here is the json
{
"_links": { },
"count": 9,
"list": {
"staff": [
"staff1",
"staff2",
"staff3"
],
"clients": [
"client1",
"client2",
"client3",
"client4",
"client5",
"client6"
]
}
}
I have also got the following code in c# but keep getting errors
string source;
var sURL = "LINK_TO_JSON_URL";
WebRequest req = HttpWebRequest.Create(sURL);
req.Method = "GET";
req.Timeout = 5000;
try
{
using (StreamReader reader = new StreamReader(req.GetResponse().GetResponseStream()))
{
source = reader.ReadToEnd();
reader.Close();
}
JToken jObject = JObject.Parse(source);
string clients = (string)jObject["list"]["clients"];
//for each loop here
}
catch (Exception ex)
{
//error message here
}
What is it that I am doing wrong? I have tried to convert string to array and still get nothing.
I want to be able to get each clients names
Cheers
So here is some code to show iterating over a JArray that contains strings. This code has been tested with your json and outputs each client string.
var jObject = JObject.Parse(source);
foreach (var client in jObject["list"]["clients"])
{
Console.WriteLine((string)client);
}
Look at this piece of code
#region Model For Deserialize String to Object
public class Links
{
}
public class List
{
public List<string> staff { get; set; }
public List<string> clients { get; set; }
}
public class RootObject
{
public Links _links { get; set; }
public int count { get; set; }
public List list { get; set; }
}
#endregion
#region Restfull Respone (String) Convert To RootObject
public class ConvertStringToObj
{
public void Execute()
{
//Your webReq and Response progress here
string jsonResponse="";
var rootObj = (RootObject)Newtonsoft.Json.JsonConvert.DeserializeObject(jsonResponse, typeof(RootObject));
foreach(var eachItem in rootObj.list.staff)
{
var stafName = eachItem;
}
}
}
#endregion
Here is an solution, you can do this via Objects :)

Deserialize JSON string to object list and write to values console

I'm trying to stream some markets data from Yahoo Finance.
I have some trouble deserialize the json stream and write it to console.
I've been through several stack overflow questions trying to put something together.
I'm unsure if I got the right code put together since I also have problems writing the result to the console.
My json data from Yahoo looks like this:
{
"ResultSet":{
"Query":"genmab",
"Result":[
{
"symbol":"GNMSF",
"name":"Genmab A/S",
"exch":"PNK",
"type":"S",
"exchDisp":"OTC Markets",
"typeDisp":"Equity"
},
{
"symbol":"GE9.F",
"name":"Genmab A/S",
"exch":"FRA",
"type":"S",
"exchDisp":"Frankfurt",
"typeDisp":"Equity"
},
{
"symbol":"GEN.F",
"name":"GENMAB AS DK 1",
"exch":"FRA",
"type":"S",
"exchDisp":"Frankfurt",
"typeDisp":"Equity"
},
{
"symbol":"GE9.BE",
"name":"GENMAB AS DK 1",
"exch":"BER",
"type":"S",
"exchDisp":"Berlin",
"typeDisp":"Equity"
},
{
"symbol":"GE9.SG",
"name":"GENMAB AS Navne Aktier DK 1",
"exch":"STU",
"type":"S",
"exchDisp":"Stuttgart",
"typeDisp":"Equity"
},
{
"symbol":"GEN.CO",
"name":"Genmab A/S",
"exch":"CPH",
"type":"S",
"exchDisp":"Copenhagen",
"typeDisp":"Equity"
},
{
"symbol":"GEN.SG",
"name":"GENMAB AS Navne Aktier DK 1",
"exch":"STU",
"type":"S",
"exchDisp":"Stuttgart",
"typeDisp":"Equity"
},
{
"symbol":"GMXAY",
"name":"Genmab A/S",
"exch":"PNK",
"type":"S",
"exchDisp":"OTC Markets",
"typeDisp":"Equity"
},
{
"symbol":"GE9.DU",
"name":"GENMAB AS DK 1",
"exch":"DUS",
"type":"S",
"exchDisp":"Dusseldorf Stock Exchange",
"typeDisp":"Equity"
},
{
"symbol":"0MGB.IL",
"name":"GENMAB A/S GENMAB ORD SHS",
"exch":"IOB",
"type":"S",
"exchDisp":"International Orderbook - London",
"typeDisp":"Equity"
}
]
}
}
The code that I've put togeter should create a list of data ojects:
using System.Web.Script.Serialization;
public class DataObject
{
public string symbol { get; set; }
public string name { get; set; }
public string exch { get; set; }
public string type { get; set; }
public string exchDisp { get; set; }
public string typeDisp { get; set; }
}
public class RootObject
{
public DataObject[] resultSet { get; set; }
}
using (WebClient web = new WebClient())
{
string _url = "http://d.yimg.com/aq/autoc?query=genmab&region=CO&lang=en-US";
var search = web.DownloadString(_url);
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<RootObject> oRootObject = serializer.Deserialize<List<RootObject>>(search);
And I'd then like to write the different data to the console
foreach (var item in oRootObject)
{
Console.WriteLine(oRootObject.???.Value.name);
}
I've tried to DeBug the flow but I can't see any data coming into the Object List.
Thanks
Flemming
After formatting your JSON, I can see that your classes don't quite map to your JSON
I used a really handy tool - http://json2csharp.com to create classes that map to your json:
public class Result
{
public string symbol { get; set; }
public string name { get; set; }
public string exch { get; set; }
public string type { get; set; }
public string exchDisp { get; set; }
public string typeDisp { get; set; }
}
public class ResultSet
{
public string Query { get; set; }
public List<Result> Result { get; set; }
}
public class RootObject
{
public ResultSet ResultSet { get; set; }
}
You can then do, as you did before:
RootObject oRootObject = serializer.Deserialize<RootObject>(search);
Inside oRootObject is another object - ResultSet
Inside ResultSet is the Result list - so that is what you want to iterate.
You'lll need to do something like this:
foreach (var item in oRootObject.ResultSet.Result)
{
Console.WriteLine(item.name);
}

Categories