I'm newbie to using the dynamic keyword in C#. It seems simple enough, but I can't seem to use it effectively.
I see this example from Facebook:
var client = new FacebookClient();
dynamic me = client.Get("totten");
string firstname = me.first_name;
it works fine, but if you look at me in a debugger, then you can see that client.Get() returns simple JSON. The same it's said in Facebook documentation:
The result of this request is a dynamic object containing various
properties such as first_name, last_name, user name, etc. You can see
the values of this request by browsing to
http://graph.facebook.com/totten in your web browser. The JSON result
is shown below.
I want to do the same dodge with returned JSON from Foursquare:
private static string GetReturnedUrlFromHttp(string url)
{
HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
webRequest.Timeout = 10000;
webRequest.Method = "GET";
WebResponse response = webRequest.GetResponse();
string responseStr = String.Empty;
using (var stream = response.GetResponseStream())
{
var r = new StreamReader(stream);
responseStr = r.ReadToEnd();
}
return responseStr;
}
public static void FillDataFromFoursquareUsingDynamic()
{
string foursquare_url_detail = "https://api.foursquare.com/v2/venues/4b80718df964a520e57230e3?locale=en&client_id=XXX&client_secret=YYY&v=10102013";
dynamic responseStr = GetReturnedUrlFromHttp(foursquare_url_detail);
var response = responseStr.response;
}
I got the following error:
'string' does not contain a definition for 'response'
Why am I getting this error and is it possible to 'parse' any JSON string like in Facebook?
FacebookClient.Get doesn't really return the JSON string. Instead it parses the string into a dynamic object with properties matching the names of the values in the JSON string.
Using dynamic doesn't magically turn a string into an object with the properties defined in the string. Instead, you need to first parse the string with the help of a JSON library like JSON.NET.
Related
This question already has answers here:
Deserialize JSON data with C#
(4 answers)
Closed 1 year ago.
I am a student working on a project. I am trying to use the Yahoo! Finance API as a source for my data https://www.yahoofinanceapi.com . I can use HttpWebRequests to call the API and get the "OK" code, see the code below on how I did it:
string BaseURL = "https://yfapi.net/v6/finance/quote?symbols=AAPL";
string addSymbol = "%2C";
string URL = BaseURL;
foreach (string stock in stocks)
{
URL += addSymbol + stock;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Headers.Add("X-API-KEY", "[My API key]");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(response.ContentType);
Console.WriteLine(response.StatusCode);
response.ContentType gives back "application/json".
response.StatusCode gives back "OK".
Since the response is a JSON I tried to parse it into a string using .ToString() but this obviously doesn't work. When I print it, it just says "System.Net.HttpWebResponse" instead of the showing the actual data in the JSON.
After that I tried to deserialize it using newtonsoft
Results result = JsonConvert.DeserializeObject<Results>(request.GetResponse().ToString());
where Results is a class I made where there is a list of stocks, Stock is also a class I made with some variables in it with the same names of variables in the JSON response.
I got a JSON response from PostMan when I tested the API, opened the response to see what kind of data it contained.
When I ran my code I got the following error message:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: S. Path '', line 0, position 0.'
This was as far as I got, I tested a few other methods trying to get this working but this one worked the "best".
My biggest issue at the moment is mapping the response into a c# object.
Anything that can help me understand is appreciated :D
You're trying to serialise the HttpWebResponse object into Results, which means deserialisation won't work.
The data is still wrapped & won't be in the format of the Results object.
The GetResponseStream() method can be used to get the contents of the HTTP response as a stream, which can then be deserialised directly, in this case, using Json.NET.
Replace this section:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(response.ContentType);
Console.WriteLine(response.StatusCode);
With this:
var serializer = new JsonSerializer();
using (var response = (HttpWebResponse)request.GetResponse())
{
var encoding = Encoding.GetEncoding(response.CharacterSet);
using var responseStream = response.GetResponseStream();
using var reader = new StreamReader(responseStream, encoding);
using (var jsonTextReader = new JsonTextReader(reader))
{
Console.WriteLine(response.ContentType);
Console.WriteLine(response.StatusCode);
Results result = serializer.Deserialize<Results>(jsonTextReader);
}
}
Alternatively, a much better solution if you're using .NET 4.5 <= would be to use HttpClient like below:
private static readonly HttpClient httpClient = new HttpClient();
...
string BaseURL = "https://yfapi.net/v6/finance/quote?symbols=AAPL";
string addSymbol = "%2C";
string URL = BaseURL;
foreach(string stock in stocks) {
URL += addSymbol + stock;
}
client.DefaultRequestHeaders.Add("X-API-KEY", "[My API key]");
var data = await httpClient.GetStringAsync(address);
Results result = JsonConvert.DeserializeObject<Results>(data);
My code here to get data from Wikipedia:
string URL = $"https://en.wikipedia.org/w/api.php?action=query&format=json&list=&titles={query}&redirects=1";
WebRequest wrREQUEST;
wrREQUEST = WebRequest.Create(URL);
wrREQUEST.Proxy = null;
wrREQUEST.Method = "GET";
WebResponse response = wrREQUEST.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
string responseData = streamReader.ReadToEnd();
JObject jsonData = JObject.Parse(responseData);
var jsonQuery = jsonData["query"];
string pageID = (string)jsonQuery;
But I keep getting
Exception thrown: 'System.ArgumentException' in Newtonsoft.Json.dll
and the json data looks like this:
{
"batchcomplete":"",
"query":{
"pages":{
"31717":{
"pageid":31717,
"ns":0,
"title":"United Kingdom"
}
}
}
}
I also want to know since "pages":{"31717":{}} is an ID which I will not know in advance, how can I get that 31717 from enumerating the data?
The error is because you are trying to explicitly convert JObject into a string, which is not possible using conversion, only by using Serilization.
But I understand you actually want the "PageId", which by the json structure, look like you need to take the "first key" from the response.
(Actually there are more ways)
So instead of
string pageID = (string)jsonQuery;
One possible way, will be using this
((JProperty)jsonQuery["pages"].First()).Name
Please find resolution of yout request, it might be possible that some time u will not get the first element value and it will trigger some exception.
Please replace your line :
string pageID = (string)jsonQuery;
with
**var jToken = jsonQuery["pages"].First;
if (jToken != null)
{
string pageID = ((JProperty) jToken).Name;
}**
Currently, I am using a [WebMethod] to call an API and get the response as a JSON string.
public string GetFloodData()
{ ...
WebRequest requestObj = WebRequest.Create(url);
requestObj.Method = "GET";
requestObj.ContentType = "application/json";
responseObj = (HttpWebResponse)requestObj.GetResponse();
using (Stream stream = responseObj.GetResponseStream())
{
StreamReader sr = new StreamReader(stream);
strresult = sr.ReadToEnd();
sr.Close();
}
return strresult;
...
}
When I call GetFloodData(), I get the following response in the browser:
<string xmlns="http://tempuri.org/">
{"ListEvents":
[{"EventID":1,"EventName":"Debby2000","State":"PR","EventType":"Tropical or
Extratropical","Days":5,"LSTStart":"\/Date(9666432000000000)\/",
"LSTEnd":"\/Dat e(967075200000-0000)\/"}, {...}....]}
At this point (before I parse it as a formal JSON Object), I just want to eliminate the stuff I don't want ("Days","LSTStart", and "LSTEnd") and keep what I want. How would I limit what attributes are returned in my response?
You can de-serialise it with a class, and in that class, you can write only the variables you do want to keep. Although, keep the structure of the Json and the class as same. Variables can be missing, but the structure should be the same
ok, so I am trying to use JSON.net to purse the JSON string of google maps API to an object:
string url = #"https://maps.googleapis.com/maps/api/directions/json?origin=75+9th+Ave+New+York,+NY&destination=MetLife+Stadium+1+MetLife+Stadium+Dr+East+Rutherford,+NJ+07073&key=YOUR_API_KEY";
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
Stream data = response.GetResponseStream();
StreamReader reader = new StreamReader(data);
string responseFromServer = reader.ReadToEnd();
response.Close();
var result = JsonConvert.DeserializeObject<T>(responseFromServer);
^
|
here
and I need to replace the T with the object that contains all the JSON fields example:
class ex
{
int[] arr;
string str;
(....)
}
however, the JSON string that returned from google maps API is very long and contains many fields, and as I'm pretty new to JSON, I will probably get this wrong. I wonder if there is a way to auto-generate a class to contain all these properties (maybe anonymous types, somehow?) or if someone did this class before me and open-sourced it?
thank you in advance!
Can you please give me a sample example of how to make the JSON request body in C#. I am using Visual Studio 2015. I know SOAP UI, but I am new to C#.
Thanks in advance.
You can try the following
Lets assume you have the following webmethod
public void Webmethod(string parameter)
{
//Do what ever
}
In C# you will do the following to call the webmethod, You require Json.net, Newtonsoft or other Json serializer
var webRequest = WebRequest.Create("http:\\www.somesite.com/path/to/webservice/webservice.asmx/Webmethod");
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
Build a Json object representing the parameters
var jsonobjectrepresentingparameters = new {parameter = "Value"};
Get the Json string using Newtonsoft JsonConvert
var datastring = Newtonsoft.Json.JsonConvert.SerializeObject(jsonobjectrepresentingparameters);
Get the bytes
var bytes = Encoding.ASCII.GetBytes(datastring);
Write the bytes to the request
var requestStream = webRequest.GetRequestStream();
requestStream.Write(bytes, 0,bytes.Length);
Get repsonse
var response = webRequest.GetResponse();
If your Webmethod returned anything like a string, int or other data you can use the following class to deserialize
public class Type<T>
{
public T D { get; set; }
public Type()
{
}
}
You will notice when you work with webservices it returns a json object with property d as the value which is why you require the above class in C#
Then you will require the following extra two lines if your return type was string
var json = (new StreamReader(response.GetResponseStream())).ReadToEnd();
var object = JsonConvert.DeserializeObject<Type<string>>(json);