Retrieve data from API call response? - c#

I'm working on an application to get some API experience with C#. I'm pulling data from a site involving jokes, but no matter what I try I can't seem to get the actual response.
I've gone over several different methods, this is the farthest I've gotten. I'm using the RestSharp library, and it's returning RestSharp.RestResponse. I've tried several different methods of deserializing this as that's what I believe is needed. From the API I'm using, the default response format is text/html. Any tips on extracting this to a string containing the joke itself would be most appreciated.
public void CreateJoke()
{
var client = new RestClient("https://icanhazdadjoke.com/");
client.AddDefaultHeader("user-agent", "Dadbot");
var request = new RestRequest("https://icanhazdadjoke.com/");
var response = client.Get(request);
lblJoke.Text = response.ToString();
}
Expected result: getting a string I can put into a label. Actual result: RestSharp.RestResponse.

Try instead accessing the Content property of response:
public void CreateJoke()
{
var client = new RestClient("https://icanhazdadjoke.com/");
client.AddDefaultHeader("user-agent", "Dadbot");
var request = new RestRequest("https://icanhazdadjoke.com/");
var response = client.Get(request);
lblJoke.Text = response.Content;
}
Hopefully that helps!

I guess this is what you want.
public string CreateJoke()
{
var request = (HttpWebRequest)WebRequest.Create("https://icanhazdadjoke.com/");
request.Method = "GET";
request.Accept = "text/plain";
var jokeResponse = request.GetResponse();
var joke = string.Empty;
using (var sr = new StreamReader(jokeResponse.GetResponseStream()))
{
joke = sr.ReadToEnd();
}
//Console.WriteLine(joke);
return joke;
}

Related

Get Data of online API

I want to download data of this website into a json file but as I am quite new to coding with C# I cant manage to get the data. I want to get Data of https://discosweb.esoc.esa.int/api/objects the authorization via token works but I dont know how I can send a request so the server gives me a json back and I cant find a solution online. I cant give you a screenshot of the API because you have to be logged in to see it. Plz ask me for detailed information if you can help me. Thank you realy for trying.
The code I want to run is here.
class Program
{
static HttpClient client = new HttpClient();
static void Main(string[] args)
{
client.BaseAddress = new Uri("https://discosweb.esoc.esa.int");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.api+json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("my_token");
var httpRequest = (HttpWebRequest)WebRequest.Create(client.BaseAddress);
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var streamReaderResult = streamReader.ReadToEnd();
}
Console.WriteLine("Status https://discosweb.esoc.esa.int : " + httpResponse.StatusCode);
}
}
Try this
var url = "https://discosweb.esoc.esa.int/api/objects";
var httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.Headers["Authorization"] = "Basic XXXx";
httpRequest.ContentType = "";
httpRequest.Headers["Content-Length"] = "0";
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Console.WriteLine(httpResponse.StatusCode);
Where XXXx is user:password in base64.
Here is a basic implementation for making that API call to get the JSON result. You will need to parse that JSON into something other than a string but I'll assume you can handle that part.
This uses System.Net.HttpClient which is the modern HTTP api provided by .NET. Its operations are async so hopefully your code is or can be written to properly await async operations.
//Someplace convenient, create a shared HttpClient to avoid
//creating and disposing for each request.
HttpClient client = new HttpClient();
string data = await GetObjects(client);
//Example implementation
public async Task<string> GetObjects(HttpClient client)
{
string url = "https://discosweb.esoc.esa.int/api/objects";
using (HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get, url))
{
msg.Headers.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your personal access token here");
using (var result = await client.SendAsync(msg))
{
string content = await result.Content.ReadAsStringAsync();
return content;
}
}
}
While I may be a month late, I've actually developed an SDK for this particular API.
So, if you use this SDK it's pretty simple to do what you want. You can essentially forget about handling anything HTTP related, my SDK abstracts all of that away.
For example, to fetch Sputnik's data (which has an ID of 1) you'd run.
HttpClient innerClient = new();
innerClient.BaseAddress = "https://discosweb.esoc.esa.int/api/"
innerClient.DefaultRequestHeaders.Authorization = new("bearer", yourApiKey);
DiscosClient client = new();
DiscosObject sputnik = await client.GetSingle<DiscosObject>("1");
If you're using ASP.NET, there's a set of DI extensions that can actually set it all up for you, so you can skip the first three lines.
If you do choose to use it, please let me know, as it would be nice knowing my SDK is getting some use. If you have any issues, please just reach out through the GitHub issues page and I'll try to help!

Get Request in C# Returning 401 Not Authorised

Currently trying to do a Get request as part of a c# program. The request works fine on Postman as it uses a header for authorization. However I cannot get the code working for the program to use this header correctly in its Get request. I've had a good look around and tried various bits of code I've found but haven't managed to resolve it so any help would be appreciated!
public string Connect()
{
using (WebClient wc = new WebClient())
{
string URI = "myURL.com";
wc.Headers.Add("Content-Type", "text");
wc.Headers[HttpRequestHeader.Authorization] = "Bearer OEMwNjI2ODQtMTc3OC00RkIxLTgyN0YtNzEzRkE5NzY3RTc3";//this is the entry code/key
string HtmlResult = wc.DownloadString(URI);
return HtmlResult;
}
}
Above is one method inside the class.
Below is another attempt which is an extension method that gets passed the URL:
public static string GetXml(this string destinationUrl)
{
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create(destinationUrl);
request.Method = "GET";
request.Headers[HttpRequestHeader.Authorization] = "Bearer
OEMwNjI2ODQtMTc3OC00RkIxLTgyN0YtNzEzRkE5NzY3RTc3";
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
string responseStr = new
StreamReader(responseStream).ReadToEnd();
return responseStr;
}
else
{
Console.Write(String.Format("{0}({1})",
response.StatusDescription, response.StatusCode));
}
return null;
}
Might I recommend the very handy RestSharp package (find it on Nuget).
It turns your current code into something like
public string Connect()
{
var client = new RestClient();
var request = new RestRequest("myURL.com", Method.GET);
request.AddParameter("Authorization", "Bearer OEMwNjI2ODQtMTc3OC00RkIxLTgyN0YtNzEzRkE5NzY3RTc3");
var response = client.Execute(request);
return response.Content;
}
It's much more succinct and easier to use (in my opinion) and thus lessens the likelihood of passing in or using incorrect methods.
If you're still having issues getting data back/connecting. Then using PostMan click Code in the upper right of PostMan and select the C# (RestSharp) option. Whatever is generated there matches exactly what PostMan is sending. Copy that over and you should get data back that matches your PostMan request.

calling rest api on client side c#

I am new to api stuff.
I want to get the result of this api(http://services.groupkt.com/country/get/all) in c# code. can you help me by suggesting any code and tutorial as well. thanks
i have tried this code but it doesnot work.
public async Task DownloadData()
{
string url = string.Format("http://services.groupkt.com/country/get/all");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
var jsonString = await client.GetStringAsync(url);
JToken token = JToken.Parse(jsonString);
foreach (var item in token)
{
txtarea.Value= item.ToString();
}
}
First of all use
client.GetStringAsync(url).Result
instead of
client.GetStringAsync(url)
Second after you received the json, it becomes very simple to parse the result. I saw the previous answeres and they were all using a loop, which is not a good idea in my opinion to parse.
Use Newtonsoft.Json library and its very handy in such situations. I've parsed your json response using this library.
Make a class of result, i.e.
public class result
{
public string name { get; set; }
public string alpha3_code { get; set; }
public string alpha2_code { get; set; }
}
put this code after getting json response for parsing your json.
JObject jsonResponse = JObject.Parse(jsonString);
JObject objResponse = (JObject)jsonResponse["RestResponse"];
Dictionary<string, JArray> _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, JArray>>(objResponse.ToString());
var results = _Data["result"].ToObject<List<result>>();
It works perfectly, I've tested this.
Don't forget to add Newtonsoft.Json AND Newtonsoft.Json.Linq namespaces
Your code fetches the response correctly. But parsing incorrectly.
Try the below full parsing code.
public async Task DownloadData()
{
string url = string.Format("http://services.groupkt.com/country/get/all");
string top_parent_key_name = "RestResponse";
string second_parent_key_name = "result";
string field_one_key_name = "name";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
var jsonString = await client.GetStringAsync(url);
JToken token = JToken.Parse(jsonString);
foreach (var item in token[top_parent_key_name][second_parent_key_name])
{
txtarea.InnerText = item[field_one_key_name].ToString();
}
}
Just to add, I would prefer dynamics here so the code communicates more clearly.
public async Task DownloadData()
{
string url = $"http://services.groupkt.com/country/get/all";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
string response = await client.GetStringAsync(url);
dynamic json = JToken.Parse(response);
foreach (var item in token.RestResponse.result)
{
//Note: Your over writing the text here for each item you pass
// Did you mean to concat instead? += "\n\r" + item.name;
txtarea.InnerText = item.ToString();
}
}
Now as for just doing txtarea.InnerText = ... in a question you labeled with "ASP.NET-Web-Api" seems a bit odd, is it an ASP.NET MVC with Web Api or a more classic Web Forms application?

C# Get Request Directus

recently i discovered this amazing cms called Directus, where you can manage your database and Tables with web request and Json.
Everything worked fine creating,updating,reading...till i came to the point where i want to Create (Upload) a Image using WebRequest.
Im basicly reading a image as Base64 and writing the data along with the parameters in the Uri using a simple GET request exactly like described in API.
Regardless what i try and use the Images Never show up in my Files.
Am i doing something wrong or forgetting something?
Or does directus want something else from me?
My first try:
public static async void UploadUserImage() {
var uri = "http://IP/Directus/api/1/files?access_token=SecretApiKey";
var data = GetImageData();
var finalUri = $"{uri}&data={data}";
using (var client = new HttpClient()) {
var responseString = await client.GetStringAsync(finalUri);
Console.Write(responseString);
}
}
My Second try with Json:
public static async void UploadUserImage() {
var uri = "http://IP/Directus/api/1/files?access_token=SecretApiKey";
var data = GetImageData();
var finalUri = $"{uri}&data={data}";
var postModel = new PictureModel {
data = data,
title = "Test",
name = "test"
};
using (var client = new HttpClient())
{
// Serialize our concrete class into a JSON String
var content = JsonConvert.SerializeObject(postModel);
var contenta = new StringContent(content, Encoding.UTF8, "application/json");
var response = await client.PostAsync(finalUri, contenta);
var result = await response.Content.ReadAsByteArrayAsync();
Console.Write(System.Text.Encoding.UTF8.GetString(result));
}
}
The docs is incorrect it's actually a POST request. Thanks for pointing that out.
To upload a new file you need three provide three values:
{
"name": "image.png",
"type": "image/png",
"data": "base64content"
}
The data content has to be in this format data:<mime-type>;base64,<data-content> so it will look something like this: data:image/png;base64,ThisIsABase64Content
We are updating the docs and removing the data:image/png which is unnecessary.

web request using API

I have done something similar to this before however I'm not sure how to do this with a bigger project.
I'm trying to return the titles of all the stuff on the front page of reddit.
From this site:
http://www.reddit.com/r/all.json
I pasted the data into
http://json2csharp.com/#
to find out the class I need.
From here though, I'm not too sure on how to proceed. If I wanted to return an array of all this data so I can easily get information, how could I do it.
Sorry for the vagueness of this question but I'm just at a loss and don't know what to do.
Use
using (var webClient = new System.Net.WebClient()) {
var json = webClient.DownloadString("http://www.reddit.com/r/all.json");
}
For old .Net:
var request = WebRequest.Create(url);
string text;
request.ContentType = "application/json; charset=utf-8";
var response = (HttpWebResponse) request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}

Categories