从HttpWebRequest转换为HttpClient

huangapple go评论69阅读模式
英文:

Converting from HttpWebRequest to HttpClient

问题

I am working with the Verizon ThingSpace API, found here.

我正在使用Verizon ThingSpace API,可以在这里找到。

I am attempting to generate the OAuth token. The API documentation provides a cURL example:

我正在尝试生成OAuth令牌。API文档提供了一个cURL示例:

curl -X POST -d "grant_type=client_credentials" -H "Authorization: Basic BASE64_ENCODED_APP_KEY_AND_SECRET" -H "Content-Type: application/x-www-form-urlencoded" "/api/ts/v1/oauth2/token"

I have been able to successfully replicate the cURL command in C# using the older HTTPWebRequest, but have failed to do so using the newer HttpClient.

我已成功在C#中使用较旧的HTTPWebRequest复制了cURL命令,但尝试使用较新的HttpClient时失败了。

I get a return value of:

我得到了一个返回值:

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

What is the proper way of replicating the cURL example in the API docs using the newer HttpClient class in C#? I have reviewed this answer, but it doesn't address the issue I am having with the grant_type.

如何使用较新的C# HttpClient类复制API文档中的cURL示例的正确方法是什么?我已经查看了这个答案,但它没有解决我在grant_type方面遇到的问题。

Edit:

Here is the HTTPWebRequest implementation, which is working as expected:

以下是HTTPWebRequest的实现,它按预期工作:

public static void API_Login()
{
    Console.WriteLine("API Request ----------------------------------");
    string url = @"https://thingspace.verizon.com/api/ts/v1/oauth2/token";
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentType = "application/x-www-form-urlencoded";
    httpWebRequest.Headers.Add("Authorization", $"Basic {encodedKeyAndSecret}");
    var body = "grant_type=client_credentials";
    var data = Encoding.ASCII.GetBytes(body);
    httpWebRequest.ContentLength = data.Length;
    using (var stream = httpWebRequest.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }
    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
        var result = streamReader.ReadToEnd();
        JsonObject jsonObject = (JsonObject)JsonObject.Parse(result);
        apiToken = jsonObject["access_token"].ToString();
    }
}

And here is HttpClient implementation, which is not working correctly:

以下是HttpClient的实现,它无法正常工作:

public async static void HttpClient_API_Login(string encodedKeyAndSecret)
{
    string url = @"https://thingspace.verizon.com/api/ts/v1/oauth2/token";
    var client = new HttpClient();
    var body = "grant_type=client_credentials";
    var request = new HttpRequestMessage()
    {
        Method = HttpMethod.Post,
        RequestUri = new Uri(url),
        Headers =
        {
            { HttpRequestHeader.ContentType.ToString(), "application/x-www-form-urlencoded" },
            { HttpRequestHeader.Authorization.ToString(), $"Basic {encodedKeyAndSecret}" },
        },
        Content = new StringContent(body)
    };
    var response = client.SendAsync(request).Result;
    var sr = await response.Content.ReadAsStringAsync();
    Console.WriteLine("response: " + sr);
}
英文:

I am working with the Verizon ThingSpace api, found here.

I am attempting to generate the Oauth token. The API documentation provides a curl example:

curl -X POST -d "grant_type=client_credentials" -H "Authorization: Basic BASE64_ENCODED_APP_KEY_AND_SECRET" -H "Content-Type: application/x-www-form-urlencoded" "/api/ts/v1/oauth2/token"

I have been able to successfully replicate the curl command in C# using the older HTTPWebRequest, but have failed to do so using the newer HttpClient.

I get a return value of:

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

What is the proper way of replicating the curl example in the API docs using the newer HttpClient class in c#? I have reviewed this answer, but it doesn't address the issue I am having with the grant_type.

Edit:

Here is the HTTPWebRequest implementation, which is working as expected:

  public static void API_Login()

{

    Console.WriteLine("API Request ----------------------------------");

    string url = @https://thingspace.verizon.com/api/ts/v1/oauth2/token;

    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

    httpWebRequest.Method = "POST";

    httpWebRequest.ContentType = "application/x-www-form-urlencoded";

    httpWebRequest.Headers.Add("Authorization", $"Basic {encodedKeyAndSecret}");

    var body = "grant_type=client_credentials";

    var data = Encoding.ASCII.GetBytes(body);

    httpWebRequest.ContentLength = data.Length;



    using (var stream = httpWebRequest.GetRequestStream())

    {

        stream.Write(data, 0, data.Length);

    }



    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))

    {

        var result = streamReader.ReadToEnd();

        JsonObject jsonObject = (JsonObject)JsonObject.Parse(result);

        apiToken = jsonObject["access_token"].ToString();

    }

}

And here is HttpClient implementation, which is not working correctly:

    public async static void HttpClient_API_Login(string encodedKeyAndSecret)

{

    string url = @https://thingspace.verizon.com/api/ts/v1/oauth2/token;

    var client = new HttpClient();

    var body = "grant_type=client_credentials";

    var request = new HttpRequestMessage()

    {

        Method = HttpMethod.Post,

        RequestUri = new Uri(url),

        Headers =

        {

            { HttpRequestHeader.ContentType.ToString(), $"application/x-www-form-urlencoded" },

            { HttpRequestHeader.Authorization.ToString(), $"Basic {encodedKeyAndSecret}" },

        },

        Content = new StringContent(body)

    };



    var response = client.SendAsync(request).Result;

    var sr = await response.Content.ReadAsStringAsync();

    Console.WriteLine("response: " + sr);

}

答案1

得分: 0

以下是翻译好的部分:

"我已经通过以下方式自行解决了这个问题:

public async static void HttpClient_API_Login(string encodedKeyAndSecret)
{   
    string url = @"https://thingspace.verizon.com/api/ts/v1/oauth2/token";
    var client = new HttpClient();
    var formData = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("grant_type", "client_credentials")
    };
    var request = new HttpRequestMessage()
    {
        Method = HttpMethod.Post,
        RequestUri = new Uri(url),
        Headers =
        {
            { HttpRequestHeader.ContentType.ToString(), "application/x-www-form-urlencoded" },
            { HttpRequestHeader.Authorization.ToString(), $"Basic {encodedKeyAndSecret}" },
        },
        Content = new FormUrlEncodedContent(body)
    };
}

问题是请求体应为表单内容,而不是字符串内容。"

英文:

I have since solved the issue on my own by changing the code as follows:

public async static void HttpClient_API_Login(string encodedKeyAndSecret)

{

string url = @https://thingspace.verizon.com/api/ts/v1/oauth2/token;

var client = new HttpClient();


var formData = new List&lt;KeyValuePair&lt;string, string&gt;&gt;

{

    new KeyValuePair&lt;string, string&gt;(&quot;grant_type&quot;, &quot;client_credentials&quot;)

};

var request = new HttpRequestMessage()

{

    Method = HttpMethod.Post,

    RequestUri = new Uri(url),

    Headers =

    {

        { HttpRequestHeader.ContentType.ToString(), $&quot;application/x-www-form-urlencoded&quot; },

        { HttpRequestHeader.Authorization.ToString(), $&quot;Basic {encodedKeyAndSecret}&quot; },

    },

    Content = new FormUrlEncodedContent(body)

};

The issue was that the body was string content, not form content.

huangapple
  • 本文由 发表于 2023年4月11日 05:27:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980882.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定