【问题标题】:How to use HttpClient to Post with Authentication如何使用 HttpClient 通过身份验证发布
【发布时间】:2015-06-16 04:36:41
【问题描述】:

我正在尝试使用 HttpClient 在 C# 中执行以下 curl(对我有用)。

curl -X POST http://www.somehosturl.com \
     -u <client-id>:<client-secret> \
     -d 'grant_type=password' \
     -d 'username=<email>' \
     -d 'password=<password>' \
     -d 'scope=all

C# 代码:

HttpClientHandler handler = new HttpClientHandler { Credentials = new  
            System.Net.NetworkCredential ("my_client_id", "my_client_secret")
    };


    try
    {
        using(var httpClient = new HttpClient(handler))
        {
            var activationUrl = "www.somehosturl.com";

            var postData = "grant_type=password&username=myemail@myemail.com&password=mypass&scope=all";
            var content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");

            var response = await httpClient.PostAsync(activationUrl, content);
            if(!response.IsSuccessStatusCode)
                return null;

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

            return result;
        }
    }
    catch(Exception)
    {
        return null;
    }

执行时,只是崩溃,甚至没有捕获异常

通常我能够很好地 GET 和 POST,但让我失望的是如何设置身份验证内容(client-id 和 client-secret)

【问题讨论】:

  • 崩溃是什么意思?你在VS里面运行这个吗?您是否开启了首次机会例外?
  • 看看这篇 Stackoverflow 帖子是否有帮助:stackoverflow.com/a/23914662/1337635
  • 能否请您发布您的代码,包括方法签名。
  • 尝试启用 CLRE(从 VS:转到 'DEBUG','Exceptions',检查 'Common Language Runtime Exceptions' 选项('Thrown' 列),然后按 'OK'。然后尝试运行再次输入您的代码(这只会为您提供有关应用崩溃原因的更多信息,当然不会解决您的问题)
  • 永远不要这样捕获异常!您只是忽略了异常,甚至没有发现它是哪种异常。你最好只删除 try/catch 块。更糟糕的是,添加代码以向自己显示异常以进行故障排除。

标签: c# .net httpclient


【解决方案1】:

首先,您必须使用您的&lt;clientid&gt;&lt;clientsecret&gt; 设置Authorization-Header。

您应该使用FormUrlEncodedContent 而不是StringContent,如下所示:

var client = new HttpClient();
client.BaseAddress = new Uri("http://myserver");
var request = new HttpRequestMessage(HttpMethod.Post, "/path");

var byteArray = new UTF8Encoding().GetBytes("<clientid>:<clientsecret>");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

var formData = new List<KeyValuePair<string, string>>();
formData.Add(new KeyValuePair<string, string>("grant_type", "password"));
formData.Add(new KeyValuePair<string, string>("username", "<email>"));
formData.Add(new KeyValuePair<string, string>("password", "<password>"));
formData.Add(new KeyValuePair<string, string>("scope", "all"));

request.Content = new FormUrlEncodedContent(formData);
var response = await client.SendAsync(request);

【讨论】:

  • 您应该解释为什么这是问题的答案。你想说除了必须设置身份验证标头之外,OP 以错误的方式传递 post 数据吗?
  • 谢谢亚历山大,这很好用!我使用的是 Xamarin,所以我不能使用 Encoding.ASCII,我必须使用新的 UTF8Encoding().GetBytes()。
  • 你为什么用client.DefaultRequestHeaders.Authorization而不是request.Headers.Authorization
【解决方案2】:

尝试将您的凭据直接放入 HttpClient 的 headers 属性中。

using (var client = new HttpClient()) {
       var byteArray = Encoding.ASCII.GetBytes("my_client_id:my_client_secret");
       var header = new AuthenticationHeaderValue("Basic",Convert.ToBase64String(byteArray));
       client.DefaultRequestHeaders.Authorization = header;

       return await client.GetStringAsync(uri);
}

【讨论】:

    【解决方案3】:

    BasicAuthenticationHeaderValue

    httpClient.DefaultRequestHeaders.Authorization
        = new BasicAuthenticationHeaderValue("login", "password");
    

    【讨论】:

    • 您写过关于 BasicAuthenticationHeaderValue 的文章,但提供了指向 AuthenticationHeaderValue 的链接,因此您的示例在 .Net 5 中无效。
    猜你喜欢
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2014-12-25
    相关资源
    最近更新 更多