asp.net httpclient显示否定答案

ego6inou  于 5个月前  发布在  .NET
关注(0)|答案(1)|浏览(76)

首先是创建token的函数,然后调用GetClient(真实的token)

public static HttpClient GetClient(string token)
{
  HttpClient client = new HttpClient();
  HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("ContentType", "application/json"), new KeyValuePair<string, string>("Authorization", "Bearer '" + token + "'") });
  var response = client.PostAsync(new Uri("https://api.sandbox.paypal.com/v2/checkout/orders"), content).Result;
  if (response.IsSuccessStatusCode)
  {
    var responseContent = response.Content;
    string responseString = responseContent.ReadAsStringAsync().Result;
  }
  return client;
}

字符串
错误是:

{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{Paypal-Debug-Id: 5341e7ff8a884
Cache-Control: no-store, must-revalidate, no-cache, max-age=0
Date: Mon, 10 Feb 2020 05:36:37 GMT
Content-Length: 244
Content-Type: application/json
}}


这种事有什么解决办法?

dxxyhpgq

dxxyhpgq1#

HTTP请求有两个主要部分,你必须理解才能做到这一点:

  • 报头
  • 内容

Header是HTTP请求的第一部分,包含有关请求的信息,如授权,内容长度,内容格式等。
第二部分是内容。这是你想要传递给服务器的实际数据。内容可以用许多不同的方式格式化,你的头应该通知服务器使用哪种格式。在你的片段中引用的两种格式是:

  • Form Url/Encoded -这种数据类型通常用于HTML表单。
<form>
    <input name="key1" value="value1"/>
    <input name="key2" value="value2"/>
</form>

字符串
该表单数据被编码为key1=value1&key2=value2

  • JSON -这是你想用来调用PayPal API的东西,它基本上只是Json结构,作为内容附加适当的头,通知服务器它应该将内容解析为Json。

您遇到问题是因为您将头部与内容和Form/UrlEncoded和Json内容类型合并。FormUrlEncodedContent构造函数需要表单键/值对的列表,而不是头部,当您向其传递内容类型和授权时,这些键/值对被视为数据,不是头。这是401错误的来源,因为服务器正在寻找授权头,而不是内容中的键/值对。尝试类似这样的东西:

public static HttpClient GetClient(string token)
{
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var yourContent = new
    {
        key1 = "value1",
        key2 = "value2"
    };
    var jsonContent = JsonConvert.SerializeObject(yourContent);
    var content = new StringContent(jsonContent, Encoding.ASCII, "application/json");

    var response = client.PostAsync(new Uri("https://api.sandbox.paypal.com/v2/checkout/orders"), content).Result;
    if (response.IsSuccessStatusCode)
    {
        var responseContent = response.Content;
        string responseString = responseContent.ReadAsStringAsync().Result;
    }
    return client;
}


首先,我将身份验证从content移到了header,你只需要创建一个新的AuthenticationHeaderValue,并将"Bearer"作为scheme传递(我没有查过,但从你的代码中,我假设API使用了Bearer身份验证方案)。
接下来,似乎你想使用Json content-type。所以你必须将Json生成为内容。我使用匿名数据类型并将其传递给JsonConvert(你需要Newtonsoft.Json包,如果你复制此代码,Visual Studio会自动建议安装该包)。
最后,要向请求添加JSON内容,您应该使用StringContent并传递生成的JSON字符串和内容类型"application/json"
编辑:测试了你的代码,我假设你的最新错误不再是401,而是400 - Bad Request,由无效的内容结构引起。或者它可能是由无效的令牌解析引起的401(也许响应长度有点不同?)。无论哪种方式,更新代码以正确地将对象来回转换为JSON。

public class TokenResponse
{
    [JsonProperty(PropertyName = "scope")]
    public string Scope { get; set; }

    [JsonProperty(PropertyName = "access_token")]
    public string AccessToken { get; set; }

    [JsonProperty(PropertyName = "token_type")]
    public string TokenType { get; set; }

    [JsonProperty(PropertyName = "app_id")]
    public string AppId { get; set; }

    [JsonProperty(PropertyName = "expires_in")]
    public int ExpiresIn { get; set; }

    [JsonProperty(PropertyName = "nonce")]
    public string Nonce { get; set; }
}

public class Amount
{
    [JsonProperty(PropertyName = "currency_code")]
    public string CurrencyCode { get; set; }

    [JsonProperty(PropertyName = "value")]
    public string Value { get; set; }
}

public class PurchaseUnit
{
    [JsonProperty(PropertyName = "amount")]
    public Amount Amount { get; set; }
}

public class OrdersRequest
{
    [JsonProperty(PropertyName = "intent")]
    public string Intent { get; set; }

    [JsonProperty(PropertyName = "purchase_units")]
    public PurchaseUnit[] PurchaseUnits { get; set; }
}

public static void CreateToken()
{
    var client = new HttpClient();
    byte[] authBytes = Encoding.ASCII.GetBytes("user:pass");
    string base64Auth = Convert.ToBase64String(authBytes);
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64Auth);

    var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("grant_type", "client_credentials") });
    var response = client.PostAsync(new Uri("https://api.sandbox.paypal.com/v1/oauth2/token"), content).Result;
    if (response.IsSuccessStatusCode)
    {
        var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(response.Content.ReadAsStringAsync().Result);
        GetClient(tokenResponse.AccessToken);
    }
}

public static HttpClient GetClient(string token)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var request = new OrdersRequest
    {
        Intent = "CAPTURE",
        PurchaseUnits = new PurchaseUnit[] { new PurchaseUnit
            {
                Amount = new Amount
                {
                    CurrencyCode = "USD",
                    Value = "100.0"
                }
            }
        }
    };

    var jsonContent = JsonConvert.SerializeObject(request);
    var content = new StringContent(jsonContent, Encoding.ASCII, "application/json");

    var response = client.PostAsync(new Uri("https://api.sandbox.paypal.com/v2/checkout/orders"), content).Result;
    if (response.IsSuccessStatusCode)
    {
        var responseString = response.Content.ReadAsStringAsync().Result;
    }
    return client;
}

相关问题