I'm trying to get data from https://ndb.nal.usda.gov, basing on instructions provided here https://ndb.nal.usda.gov/ndb/doc/apilist/API-FOOD-REPORT.md
I'm using HttpClient as follows, but can't seem to be able to pass the api_key correctly. Shouldn't I be adding it to headers? I tried
public static async Task<string> DownloadItemData(string itemName)
{
using (HttpClient client = new HttpClient())
{
HttpContent requestContent =
new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("api_key", "myKey"),
new KeyValuePair<string, string>("ndbno", "01009"),
new KeyValuePair<string, string>("type", "f")
});
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = await client.PostAsync("http://api.nal.usda.gov/ndb/reports", requestContent);
using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
// Write the output.
string result = await reader.ReadToEndAsync();
return result;
}
}
But all I'm getting is:
{
"error": {
"code": "API_KEY_MISSING",
"message": "No api_key was supplied. Get one at http://api.nal.usda.gov"
}
}
I also tried this, but with the same result:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("api_key", "myKey");
Any ideas how to pass the api_key correctly? Thanks in advance!
Related
I am getting error cannot send a content-body with this verb-type. I am calling a GET Endpoint from a C# VSTO desktop application. What am I doing wrong.
public static string GetCentralPath(LicenseMachineValidateRequestDTO licenseMachine)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Properties.Settings.Default.Properties["JWT"].DefaultValue.ToString());
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri($"{Constants.URL.APIBase}licensemachine/GetCentralPath"),
Content = new StringContent(JsonConvert.SerializeObject(licenseMachine), Encoding.UTF8, "application/json"),
};
using (HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult()) // Causing ERROR
{
var result = GetStringResultFromHttpResponseMessage(response, true);
if (string.IsNullOrEmpty(result))
return null;
return JsonConvert.DeserializeObject<string>(result);
}
}
}
The end point looks like the following:
[HttpGet("GetCentralPath")]
public async Task<IActionResult> GetCentralPath(LicenseMachineValidateRequestDTO dto)
{
// Some code
}
fix the action, you cannot send body data with get, see this post
HTTP GET with request body
[HttpPost("GetCentralPath")]
public async Task<IActionResult> GetCentralPath(LicenseMachineValidateRequestDTO dto)
and fix request , replace Method = HttpMethod.Get with Post, this is what generates an error
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri($"{Constants.URL.APIBase}licensemachine/GetCentralPath"),
Content = new StringContent(JsonConvert.SerializeObject(licenseMachine), Encoding.UTF8, "application/json"),
};
I'm using this method, I recover the error "The interruption of an existing connection has been forced by the remote host"
public static async void GetAccessToken()
{
var client = new HttpClient();
// Create the HttpContent for the form to be posted.
var requestContent = new FormUrlEncodedContent(
new[] {
new KeyValuePair<string, string>("client_secret","xxxxx"),
new KeyValuePair<string, string>("client_id","xxxxx"),
new KeyValuePair<string, string>("grant_type","authorization_code"),
new KeyValuePair<string, string>("redirect_uri","http://localhost"),
new KeyValuePair<string, string>("code","xxxxx")
});
// Get the response.
HttpResponseMessage response = await client.PostAsync(
"https://domain-uber.com/oauth/v2/token",
requestContent);
// Get the response content.
HttpContent responseContent = response.Content;
// Get the stream of the content.
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
var result = await reader.ReadToEndAsync();
}
}
i'm trying to send a post request to an online API to recieve net data, it was succesfull with normal key-value's but not with array's as value and i could't find it on the internet without creating a big amount of extra classes.
This is how i tried to post to the url with normal data (the 3th one needs an array in stead of a single object).
IEnumerable<KeyValuePair<string, string>> queries = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("keyA","ValueA"),
new KeyValuePair<string, string>("keyB", ""),
new KeyValuePair<string, string>("KeyC", "ValueCDE"), //array
};
HttpContent q = new FormUrlEncodedContent(queries);
Console.WriteLine(q.ToString());
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.PostAsync(url, q))
{
using (HttpContent content = response.Content)
{
string mycontent = await content.ReadAsStringAsync();
HttpContentHeaders headers = content.Headers;
Console.WriteLine(mycontent);
Console.WriteLine(response);
}
}
}
I tried to send raw data to the url but i recieved no response from it.
async static void PostRawRequest(string url)
{
string rawr = #"{
""a"":""a"",
""b"":"""",
""c"": [""C"", ""D"",""F""],
""StickerColor"": ""red""
}";
string result = "";
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
result = client.UploadString(url, "POST", rawr);
}
Console.WriteLine(result);
}
Can anyone help me in either the first(sending array values) or second (sending raw data)?
If you can, use a library to handle the serialization for you. Then you can do something like this (using Newtonsoft.Json):
using (var client = new HttpClient())
{
var json = JsonConvert.SerializeObject(yourObject);
client.PostAsync(yourUri, new StringContent(json, Encoding.UTF8, "application/json"));
}
Still being new to C#, I am sure that I am not using the HttpClient library properly. I am trying to authenticate with the Works With Nest API so that I can read/write requests to a thermostat. Below is the code that I am using to authenticate:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Http.Headers;
namespace iConnect.Controllers
{
public class NestController : Controller
{
static HttpClient client = new HttpClient();
public IActionResult Index()
{
return View();
}
public async Task<HttpResponseMessage> GetNestAuthCode()
{
// Nest Pin Code
String pincode = "MYPING";
String clientID = "My-Client-ID";
String clientSecret = "MySecretString";
String grantType = "authorization_code";
client.BaseAddress = new Uri("https://api.home.nest.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/access_token");
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("code", pincode)
, new KeyValuePair<string, string>("client_id", clientID)
, new KeyValuePair<string, string>("client_secret", clientSecret)
, new KeyValuePair<string, string>("grant_type", grantType)
};
//var content = new FormUrlEncodedContent(data);
//await content.ReadAsByteArrayAsync();
//content.Add(data);
request.Content = new FormUrlEncodedContent(data);
//HttpResponseMessage response = await client.PostAsync(client.BaseAddress, content);
HttpResponseMessage response = await client.SendAsync(request);
return response;
}
}
}
When I go to localhost:9387/Nest/GetAuthCode, I get the following JSON response:
{
"version":{
"major":1,
"minor":1,
"build":-1,
"revision":-1,
"majorRevision":-1,
"minorRevision":-1
},
"content":{
"headers":[
{
"key":"Content-Type",
"value":[
"application/json"
]
}
]
},
"statusCode":400,
"reasonPhrase":"Bad Request",
"headers":[
{
"key":"Connection",
"value":[
"keep-alive"
]
}
],
"requestMessage":{
"version":{
"major":1,
"minor":1,
"build":-1,
"revision":-1,
"majorRevision":-1,
"minorRevision":-1
},
"content":{
"headers":[
{
"key":"Content-Type",
"value":[
"application/x-www-form-urlencoded"
]
},
{
"key":"Content-Length",
"value":[
"130"
]
}
]
},
"method":{
"method":"POST"
},
"requestUri":"https://api.home.nest.com/oauth2/access_token",
"headers":[
{
"key":"Accept",
"value":[
"application/json"
]
}
],
"properties":{
}
},
"isSuccessStatusCode":false
}
Any assistance is greatly appreciated. Thank you.
EDIT:
I've made the following changes and get the following response (which is not what I expect):
Code:
public async Task<ActionResult> GetNestAuthCode()
{
// Nest Pin Code
String pincode = "MYPING";
String clientID = "My-Client-ID";
String clientSecret = "MySecretString";
String grantType = "authorization_code";
client.BaseAddress = new Uri("https://api.home.nest.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/access_token");
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("code", pincode)
, new KeyValuePair<string, string>("client_id", clientID)
, new KeyValuePair<string, string>("client_secret", clientSecret)
, new KeyValuePair<string, string>("grant_type", grantType)
};
//var content = new FormUrlEncodedContent(data);
//await content.ReadAsByteArrayAsync();
//content.Add(data);
//request.Content = new FormUrlEncodedContent(data);
//HttpResponseMessage response = await client.PostAsync(client.BaseAddress, content);
var response = await client.PostAsync("oauth2/access_token",
new FormUrlEncodedContent(data));
var content = await response.Content.ReadAsStringAsync();
return Content(content);
}
Response:
{"error":"oauth2_error","error_description":"authorization code not found","instance_id":"f64d5268-8bec-4799-927c-e53454ed96d5"}
You're returning you're whole response message back from your action method, with all its properties and values. Instead, you should just read its content and return that. You can find a good article on using the built in .NET HttpClient right here, if you'd like.
What I would do, is the following:
public async Task<IActionResult> GetNestAuthCode()
{
// HttpClient setup...
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("code", "MYPING"),
new KeyValuePair<string, string>("client_id", "My-Client-ID"),
new KeyValuePair<string, string>("client_secret", "MySecretString"),
new KeyValuePair<string, string>("grant_type", "authorization_code")
});
var response = await client.PostAsync("oauth2/access_token", content);
// Or check instead with IsSuccessStatusCode
response.EnsureSuccessStatusCode();
// ReadAsStringAsync() is just an example here
var responseContent = await response.Content.ReadAsStringAsync();
return Content(responseContent);
}
Note that...
I'm still using an IActionResult (or actually Task<IActionResult>) as return type. You shouldn't return the response object.
I'm directly using the PostAsync() method with the relevant content as FormUrlEncodedContent, instead of first building an HttpRequestMessage and using SendAsync().
Also don't forget to check if your request was successful! Otherwise, you might be returning an error message from your action method instead.
I'm just using ReadAsStringAsync() and return Content() as an example.
Please note that there is something wrong with your request to the Nest API though, since it returns 400 Bad Request. You should be able to derive what exactly from the error message in the content. ;)
EDIT
I had a very quick look at the Nest API, and I think you're giving the wrong value for code. Instead of specifying your PIN code, I think you should first call another API method to retrieve an authorization code before you can exchange it for an access token (as seen here).
I have deployed an AzureML published experiment with deployed web service. I tried to use the sample code provided in the configuration page, but universal apps do not implement Http.Formatting yet, thus I couldn't use postasjsonasync.
I tried to follow the sample code as much as possible, but I'm getting statuscode of 415 "Unsupported Media Type", What's the mistake I'm doing?
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
// client.BaseAddress = uri;
var scoreRequest = new
{
Inputs = new Dictionary<string, StringTable>() {
{
"dataInput",
new StringTable()
{
ColumnNames = new [] {"Direction", "meanX", "meanY", "meanZ"},
Values = new [,] { { "", x.ToString(), y.ToString(), z.ToString() }, }
}
},
},
GlobalParameters = new Dictionary<string, string>() { }
};
var stringContent = new StringContent(scoreRequest.ToString());
HttpResponseMessage response = await client.PostAsync(uri, stringContent);
Many Thanks
You'll need to serialize the object to a JSON string (I recommend using NewtonSoft.Json to make it easier) and set the content type accordingly. Here's an implementation I'm using in my UWP apps (note that _client is an HttpClient):
public async Task<HttpResponseMessage> PostAsJsonAsync<T>(Uri uri, T item)
{
var itemAsJson = JsonConvert.SerializeObject(item);
var content = new StringContent(itemAsJson);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return await _client.PostAsync(uri, content);
}