Read specific object data from json - c#

I want to get specific object data from json from url the following code give me. i need the second object 'EmailAddressSuffices'
WebRequest request = WebRequest.Create(
"https://atea-dev.accesscontrol.windows.net/v2/metadata/IdentityProviders.js?protocol=wsfederation&realm=https%3a%2f%2flocalhost%3a44300%2fAccount%2fLoginCallback%2f&reply_to=https%3a%2f%2flocalhost%3a44300%2fAccount%2fLoginCallback%2f&context=&request_id=&version=1.0&callback=");
request.Credentials = CredentialCache.DefaultCredentials;
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();

Using JSON.Net you can deserialize the JSON response easily:
Solution 1
1. Create a class to map your JSON into:
public class ResponseObject
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("LoginUrl")]
public string LoginUrl { get; set; }
[JsonProperty("LogoutUrl")]
public string LogoutUrl { get; set; }
[JsonProperty("ImageUrl")]
public string ImageUrl { get; set; }
[JsonProperty("EmailAddressSuffixes")]
public IList<string> EmailAddressSuffixes { get; set; }
}
2. Deserialize your JSON using JsonConvert.Deserialize<ResponseObject>()
var myresponse = JsonConvert.DeserializeObject<List<ResponseObject>>(responseFromServer);
string email = myresponse[1].EmailAddressSuffixes[0];
Solution 2
If you don't want to bother with derializing the entire thing then you can do this:
JArray array = JArray.Parse(responseFromServer);
string q = array[1]["EmailAddressSuffixes"][0].ToString();
But you should make sure that your object has the right format (and the right number of items in the array.

Related

unable to put deserialized json into gridview

Gridview unable to get json data due to invalid data type. From what i understand it needs a List<> data source. How do i make my data populate my gridview?
The received JSON from the api
{"BTC":{"SGD":4864.11,"USD":3617.33,"EUR":3162.71}}
...
public class BTC
{
public double SGD { get; set; }
public double USD { get; set; }
public double EUR { get; set; }
}
public class CryptoPrice
{
public BTC BTC { get; set; }
}
...
var webRequest = (HttpWebRequest)WebRequest.Create("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=SGD,USD,EUR&api_key=<secret_key>");
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webResponse.StatusCode == HttpStatusCode.OK)
{
JavaScriptSerializer json = new JavaScriptSerializer();
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
string resString = sr.ReadToEnd();
CryptoPrice list = json.Deserialize<CryptoPrice>(resString);
GridView1.DataSource = list.BTC;
GridView1.DataBind();
}
I’m not 100% sure but your data source is not a list. As you can see in your code you’re deserializing returned Json to only one instance of CryptoPrice type. Try deserializing it to List<CryptoPrice> and assign it as data source to your grid view.

c# Json to object list

I have a function that accesses a API and retrieves some Json values, these values are returned and pasted into a rich textbox. How am I able to convert this Json into a object list? The internet is filled with what i am asking but i'm not getting any wiser after reading and trying it all.
This is the function, URL is the Api link that retrieves the Json.
public string GetApi(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
throw;
}
}
This is the Json structure
{"id":19684,"buys":[{"listings":10,"unit_price":94,"quantity":2498},{"listings":42,"unit_price":93,"quantity":10398},{"listings":139,"unit_price":92,"quantity":34501},{"listings":8,"unit_price":91,"quantity":1939},{"listings":38,"unit_price":90,"quantity":9270},{"listings":7,"unit_price":89,"quantity":1266},{"listings":43,"unit_price":88,"quantity":10565},{"listings":23,"unit_price":87,"quantity":5476},{"listings":80,"unit_price":86,"quantity":19827},
The first order of business is to use a library to parse the JSON. For this answer I use Newtonsoft.Json, one of the most used JSON libraries for .NET.
Then, the structure of the document you receive from the server should be identified. I'm just guessing here, but I assume it's something like the classes defined below. The JsonProperty is an attribute to specify the field name from the JSON document mapping to the property. It isn't necessary to specify this, only when your property names are different from the field names in the JSON document. In this case, unit_price does not match the standard .NET PascalCase naming convention for properties.
public class Listings
{
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
public List<Buy> Buys { get; private set; }
public Listings()
{
Buys = new List<Buy>();
}
}
public class Buy
{
[JsonProperty(PropertyName = "listings")]
public int Listings { get; set; }
[JsonProperty(PropertyName = "unit_price")]
public int UnitPrice { get; set; }
[JsonProperty(PropertyName = "quantity")]
public int Quantity { get; set; }
}
Once you have defined the class structure, you can let the library do all of the work. Look into the documentation for more details, here is how you would retrieve the list inside the method you already wrote.
public Listings GetApi(string url)
{
...
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
var jsonReader = new JsonTextReader(reader);
var serializer = new JsonSerializer();
return serializer.Deserialize<Listings>(jsonReader);
}
...
}

c# Deserialize json into List

I have this code that retrieves Json string from API link. The Json is deserialized and returned to a textbox. This works perfectly as long as there is only 1 Json value, being returned more than 1 value it crashes with this error:
Additional information: Cannot deserialize the current JSON array
(e.g. [1,2,3]) into type 'GW2_tradingPost.RootObject' 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.
Doing my research this happens because there is nowhere to deposit the Json since its not an List.
I've have tried this code and various similar ones.
List<RootObject> list = JsonConvert.DeserializeObject<List<RootObject>>(jsonReader.ToString());
return list;
This will return with error:
Error 1 Cannot implicitly convert type
'System.Collections.Generic.List' to
'GW2_tradingPost.RootObject' e:\mega\gw2_tradingpost\gw2_tradingpost\api_request.cs 34
Which i dont fully understand what it means.
Here is my full code.
api_Request.cs
public class api_Request
{
public RootObject GetApi(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
var jsonReader = new JsonTextReader(reader);
var serializer = new JsonSerializer();
return serializer.Deserialize<RootObject>(jsonReader);
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
throw;
}
}
}
public class Buy
{
public int listings { get; set; }
public int unit_price { get; set; }
public int quantity { get; set; }
}
public class Sell
{
public int listings { get; set; }
public int unit_price { get; set; }
public int quantity { get; set; }
}
public class RootObject
{
public int id { get; set; }
public List<Buy> buys { get; set; }
public List<Sell> sells { get; set; }
}
Form1.cs
private void button1_Click(object sender, EventArgs e)
{
RootObject RootObject = new RootObject();
api_Request api_Request = new api_Request();
richTextBox1.Text = api_Request.GetApi("https://api.guildwars2.com/v2/commerce/listings").id.ToString();
}
In this json is a single ID, so this works fine. https://api.guildwars2.com/v2/commerce/listings/19684
But when retrieving multiple ID's like here, it breaks.
https://api.guildwars2.com/v2/commerce/listings
Here is a simple solution to get listing of all id's it will a real amount of time though to go through all of them
List<RootObject> rootobject = new List<RootObject>();
using (var webclient = new WebClient())
{
var Ids = webclient.DownloadString(" https://api.guildwars2.com/v2/commerce/listings");
foreach (var id in Ids.Substring(1, s.Length-2).Split(','))
{
string url = string.Format("{0}/{1}","https://api.guildwars2.com/v2/commerce/listings",id);
var res = webclient.DownloadString(url);
var jsonObject = JsonConvert.DeserializeObject<RootObject>(res);
rootobject.Add(jsonObject);
}
}
The link that you provided for multiple ID's return an Array of Integers. I would suggest parsing this as such:
var ids = JsonConvert.DeserializeObject<int[]>(jsonReader.ToString())
As you have said, your code works for a single item, so you can use your existing code for each individual request which instead of hitting https://api.guildwars2.com/v2/commerce/listings, will be hitting https://api.guildwars2.com/v2/commerce/listings/{id} which you can use string.Format() to add where it is needed.
Seriously consider how many of the id's returned in the int[] you actually want to fetch the root object for though, as from what I can see that it returns, you will be making a hell of a lot of requests.

Deserializing JSON to List<> is not working in C#

This is the JSON i got from stream, and converted to string.
"{\"data\":[{\"thread_id\":\"1111155552222\",\"recipients\":[123123,456456],\"message_count\":2100},{\"thread_id\":\"1111155553333\",\"recipients\":[123124,456457],\"message_count\":4851},{\"thread_id\":\"1111155554444\",\"recipients\":[123125,456458],\"message_count\":435}]}"
public class DataContainer
{
List<data> data { get; set; }
}
public class data
{
public string thread_id { get; set; }
public long[] recipients { get; set; }
public int message_count { get; set; }
}
JavaScriptSerializer ser = new JavaScriptSerializer();
DataContainer data = ser.Deserialize<DataContainer>(json);
I am getting null at data, it does not seem to get deserialize. amateur in json. getting headache with this already.
Thanks!
Getting the JSON string
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(stream, encode);
string json = reader.ReadToEnd();
It seems your "JSON you got from stream and converted to string" has been serialized twice.
ASP.NET automatically JSON serializes your service methods’ responses, even if their result is an object or collection of objects
You should be able to use it directly without having to serialize/deserialize it.
Something like:
//Assuming GetJson() returns a JSON string, which you can use directly
DataContainer data = GetJson();
Check this: http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/
Also this: Reading from JSON, data not displayed

I can't decrypt text

I have url http://translate.google.ru/translate_a/t?client=x&text=ввійти вийти&sl=ua&tl=en
If you will go through this link in response you will have js file with normal translate text:
{"sentences":[{"trans":"enter exit","orig":"ввійти вийти","translit":"","src_translit":"vviy̆ty vyy̆ty"}],"src":"uk","server_time":127}
But if you get this data through program you will have encrypt translate data:
{"sentences":[{"trans":"\u00D0 \u00B2 \u00D0 \u00B2 \u00D1-\u00D0 \u00B9 \u00D1,
\u00D0 \u00B8 \u00D0 \u00B2 \u00D0 \u00B8 \u00D0 \u00B9 \u00D1, \u00D0 \u00B8",
"orig":"\u00D0\u00B2\u00D0\u00B2\u00D1?\u00D0\u00B9\u00D1?\u00D0\u00B8 \u00D0\u0
0B2\u00D0\u00B8\u00D0\u00B9\u00D1?\u00D0\u00B8","translit":"","src_translit":""}
],"src":"is","server_time":4}
Through this code i got this data.
string url = #"http://translate.google.ru/translate_a/t?client=x&text=ввійти вийти&sl=ua&tl=en";
WebRequest request = WebRequest.Create(url);
request.Timeout = 5000;
WebResponse responce = request.GetResponse();
Stream stream = responce.GetResponseStream();
StreamReader st = new StreamReader(stream);
string responsText = st.ReadToEnd();
Console.WriteLine(responsText);
Console.ReadLine();
How can i decrypt this data?
The data is not encrypted. It is encoded. If you use proper JSON deserialization, like the DataJsonContractSerializer class, this will not be a problem, because the framework will decode the data for you.
[DataContract]
public class TranslationData {
[DataMember(Name = "sentences")]
public Sentence[] Sentences { get; set; }
[DataMember(Name = "src")]
public string Source { get; set; }
[DataMember(Name = "server_time")]
public int ServerTime { get; set; }
}
[DataContract]
public class Sentence {
[DataMember(Name = "trans")]
public string Translation { get; set; }
[DataMember(Name = "orig")]
public string Original { get; set; }
[DataMember(Name = "translit")]
public string Transliteration { get; set; }
[DataMember(Name = "src_translit")]
public string SourceTransliteration { get; set; }
}
Then use the System.Runtime.Serialization.Json.DataContractJsonSerializer class for deserialization (you have to add a reference to the System.Runtime.Serialization assembly) to read from the response stream directly:
var serializer = new DataContractJsonSerializer(typeof(TranslationData));
return (TranslationData)serializer.ReadObject(theResponseStream);
There are other ways of doing this, but this way you'll get nice typed data.

Categories