HTTPClient 在尝试传递参数时导致 BadRequest

HTTPClient results in BadRequest when attempting to pass through parameters

我对打电话给 API 很陌生,我正在尝试联系以下 api: https://www.watttime.org/api-documentation/

基本上,我试图将 python 代码的两个片段转换为 c#:

中的 HttpRequest

用于登录:

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())

使用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)

这是我试图模拟该行为的 C# 代码:

 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

            }
        }

当我使用上面的代码时,使用我输入的用户名和密码获取和存储令牌的部分工作正常,我能够取回该令牌。但是,在第二个 HttpRequest 期间,我收到错误 400:错误请求。

然后我在第二个 HttpRequest 中更改了以下代码:

HttpResponseMessage response2 = await client2.GetAsync(url);

收件人:

HttpResponseMessage response2 = await client2.GetAsync(url + queryString);

在执行此操作时,我认为我正在添加所需的参数以使其成为“好请求”而不是“坏”请求。相反,然后我收到错误 404:未找到,我认为这意味着我离解决方案越来越远。归根结底,我想知道如何正确添加这些参数,以便 API 调用有效。

只需 运行 你在 Linqpad 上的查询字符串生成器告诉我

var query = HttpUtility.ParseQueryString(string.Empty);
query["latitude"] = "43.80136";
query["longitude"] = "-91.23958";
string queryString = query.ToString();

queryString.Dump();

queryString 是

latitude=43.80136&longitude=-91.23958

这意味着 url + querystring

v2/ba-from-loclatitude=43.80136&longitude=-91.23958

我怀疑你想用

调用client2.GetAsync
v2/ba-from-loc?latitude=43.80136&longitude=-91.23958

在这种情况下你想打电话给

client2.GetAsync(url + "?" + queryString);