I am very new with making calls to API, and am trying to contact the following api: https://www.watttime.org/api-documentation/
Basically, I am attempting to convert the two snippets of python code to an HttpRequest within c#:
For logging in:
import requests
from requests.auth import HTTPBasicAuth
login_url = 'https://api2.watttime.org/v2/login'
rsp = requests.get(login_url, auth=HTTPBasicAuth('freddo', 'the_frog'))
print(rsp.json())
For grabbing data with token:
import requests
from requests.auth import HTTPBasicAuth
login_url = 'https://api2.watttime.org/v2/login'
token = requests.get(login_url, auth=HTTPBasicAuth(‘freddo’, ‘the_frog’)).json()['token']
region_url = 'https://api2.watttime.org/v2/ba-from-loc'
headers = {'Authorization': 'Bearer {}'.format(token)}
params = {'latitude': '42.372', 'longitude': '-72.519'}
rsp=requests.get(region_url, headers=headers, params=params)
print(rsp.text)
Here is my c# code attempting to emulate that behavior:
private async void TestLogin()
{
var token = "";
HttpClientHandler d = new HttpClientHandler();
d.Credentials = new NetworkCredential("myUsername", "myPassword");
using (var client = new HttpClient(d))
{
client.BaseAddress = new Uri("https://api2.watttime.org");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//log in and token grab
HttpResponseMessage response = await client.GetAsync("v2/login");
if (response.IsSuccessStatusCode)
{
string apiResponse = await response.Content.ReadAsStringAsync();
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(apiResponse);
tokenValue = values["token"];
}
else
{
Console.WriteLine("Internal server Error");
}
}
using (var client2 = new HttpClient())
{
client2.BaseAddress = new Uri("https://api2.watttime.org");
client2.DefaultRequestHeaders.Accept.Clear();
client2.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenValue.ToString());
var url = "v2/ba-from-loc";
var query = HttpUtility.ParseQueryString(string.Empty);
query["latitude"] = "43.80136";
query["longitude"] = "-91.23958";
string queryString = query.ToString();
HttpResponseMessage response2 = await client2.GetAsync(url);
if (response2.IsSuccessStatusCode)
{
}
else
{
Console.WriteLine("Internal server Error Okay?");
}
//GET Method
}
}
When I use the code above, the part part that grabs and stores the token with my username and password entered works correctly and I am able to get that token back. However, during the second HttpRequest, I get an Error 400: Bad Request.
I then changed the following code within the second HttpRequest:
HttpResponseMessage response2 = await client2.GetAsync(url);
To:
HttpResponseMessage response2 = await client2.GetAsync(url queryString);
In doing this, I thought I was adding the needed parameters to make it a "good request" instead of a "bad" one. Instead, I then received an Error 404: Not Found, which I believe means I am getting further away from the solution. When it boils down, I am wondering how to correctly add these parameters so the API call works.
CodePudding user response:
Simply running your query string builder on Linqpad shows me that
var query = HttpUtility.ParseQueryString(string.Empty);
query["latitude"] = "43.80136";
query["longitude"] = "-91.23958";
string queryString = query.ToString();
queryString.Dump();
queryString is
latitude=43.80136&longitude=-91.23958
This means url querystring
is
v2/ba-from-loclatitude=43.80136&longitude=-91.23958
I suspect you want to call client2.GetAsync
with
v2/ba-from-loc?latitude=43.80136&longitude=-91.23958
In which case you want to call
client2.GetAsync(url "?" queryString);