curl正常工作,但HttpClient PostAsync无效

问题描述 投票:0回答:1

我无法在.NET中复制cUrl语句。我正在使用Oauth API(ORICD SSO),下面的curl语句可以正常工作。

curl -i -L -H "Accept: application/json" --data "client_id=APP-XXXXXXXXXXXXXXXX&client_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&grant_type=authorization_code&code=VicdvK&redirect_uri=https%3a%2f%2ftst.dev.local%2fsite%2fssocallback.aspx" "https://sandbox.orcid.org/oauth/token"

我从API中获得了所需的东西。但是,我似乎无法在C#中复制这种成功。它一直失败,并显示401未经授权。在方法1中,我尝试将数据作为JSON发送。

var postdata = new Dictionary<string, string>()
{
    { "client_id", Context.Settings.ClientId },
    { "client_secret", Context.Settings.ClientSecret },
    { "grant_type", Context.Settings.GrantType },
    { "code", Context.HttpContext.Request.Params["code"] },
    { "redirect_uri", Context.Settings.RedirectUri },
};
var jsonContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(postdata), Encoding.UTF8, "application/json");
var response = (new HttpClient())
    .PostAsync(Context.Settings.TokenUrl, jsonContent)
    .Result;

在方法2中,我尝试使用FormUrlEncodedContent,并通过客户端对其进行了更改,以设置接受标头。

var formContent = new FormUrlEncodedContent(new[]
{
    new KeyValuePair<string, string>("client_id", Context.Settings.ClientId),
    new KeyValuePair<string, string>("client_secret", Context.Settings.ClientSecret),
    new KeyValuePair<string, string>("grant_type", Context.Settings.GrantType),
    new KeyValuePair<string, string>("code", Context.HttpContext.Request.Params["code"]),
    new KeyValuePair<string, string>("redirect_uri", Context.Settings.RedirectUri)
});
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var response = client.PostAsync(Context.Settings.TokenUrl, formContent).Result;

[这不起作用时,对于方法3,我手动构建了数据字符串,以使其看起来与ORCID页面中的curl语句完全一样。我还再次更改了客户端,以为也许有一些默认的接受标头弄乱了事情。

var sb = new StringBuilder();
sb.Append("client_id=");
sb.Append(HttpUtility.UrlEncode(Context.Settings.ClientId));
sb.Append("&client_secret=");
sb.Append(HttpUtility.UrlEncode(Context.Settings.ClientSecret));
sb.Append("&grant_type=");
sb.Append(HttpUtility.UrlEncode(Context.Settings.GrantType));
sb.Append("&code=");
sb.Append(HttpUtility.UrlEncode(Context.HttpContext.Request.Params["code"]));
sb.Append("&redirect_uri=");
sb.Append(HttpUtility.UrlEncode(Context.Settings.RedirectUri));
var stringContent = new StringContent(sb.ToString(), Encoding.UTF8, "application/json");

HttpResponseMessage response;
using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

    using (var request = new HttpRequestMessage(new HttpMethod("POST"), Context.Settings.TokenUrl))
    {
        request.Content = stringContent;
        response = client.SendAsync(request).Result;
    }
}

所有这些方法均失败。在选项3失败后,我使用上面的curl语句进行了测试,并且可以正常工作!上面curl语句中的数据是直接从String Studio值中的Visual Studio的直接窗口中剥离的,因此我确定他们两个都使用相同的正确凭据。

我不知道还要测试什么。

请注意,我正在使用的网站当前托管在运行curl语句的Windows 10笔记本电脑上。

我还尝试了与Fiddler一起观看外拨电话,但是它没有从本地IIS服务器接听POST呼叫。它只会显示浏览器重定向,而不显示代码中的帖子。

c# asp.net curl http-post dotnet-httpclient
1个回答
0
投票

我知道了。基本上是方法2,除了我不应该弄乱标题:

HttpResponseMessage response;
using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Clear();
    client.DefaultRequestHeaders.Add("Accept", "application/json");

    var formContent = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("client_id", Context.Settings.ClientId),
        new KeyValuePair<string, string>("client_secret", Context.Settings.ClientSecret),
        new KeyValuePair<string, string>("grant_type", Context.Settings.GrantType),
        new KeyValuePair<string, string>("code", Context.HttpContext.Request.Params["code"]),
        new KeyValuePair<string, string>("redirect_uri", Context.Settings.RedirectUri)
    });

    response = client.PostAsync(Context.Settings.TokenUrl, formContent).Result;
}

默认情况下,FormUrlEncodedContent的标题为"Content-type", "application/x-www-form-urlencoded",这是它的必需值。不幸的是,文档没有对此进行澄清,并且直到现在我还是不明白。

© www.soinside.com 2019 - 2024. All rights reserved.