将 POST 卷曲到 C#
Posted
技术标签:
【中文标题】将 POST 卷曲到 C#【英文标题】:curl POST into C# 【发布时间】:2019-02-25 19:58:27 【问题描述】:我正在尝试找到一种将 curl 命令传输到 C# 的方法。
我需要的是从 api 获取令牌并将其保存到文件 C:\...\x.json\
然后我想将令牌声明为变量,并将其用于另一个 curl POST 请求以获取数据以使用它们。
卷曲:
curl -X POST "https://example.com"
-H "accept: application/json"
-H "Content-Type: application/json"
-d "username":"username","password":"password"
我目前的尝试:
static void Main(string[] args)
using (var httpClient = new HttpClient())
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://example.com"))
request.Headers.TryAddWithoutValidation("Accept", "application/json");
request.Content = new StringContent("\"username\":\"username\",\"password\":\"password\"", Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
我尝试了几件事,但都没有奏效。这个来自 curl.olsh.me 但我也收到了一些等待错误,我不知道如何处理它。 (我是 C# 的新手):
“await”运算符只能在异步方法中使用。考虑使用 'async' 修饰符标记此方法并将其返回类型更改为 'Task'。
curl -v 输出:
正在尝试 10.0.0.0... TCP_NODELAY 设置 已连接到 example.com (10.0.0.0) 端口 443 (#0) ALPN,提供 h2 ALPN,提供 http/1.1 成功设置证书验证位置: CAfile: C:\Users\lvrabel\Downloads\curl-7.60.0-win64-mingw\curl-7.60.0-win64-mingw\bin\curl-ca-bundle.crt CApath:无 TLSv1.2 (OUT)、TLS 握手、客户端问候 (1): TLSv1.2 (IN)、TLS 握手、服务器问候 (2): TLSv1.2 (IN)、TLS 握手、证书 (11): TLSv1.2 (IN)、TLS 握手、服务器密钥交换 (12): TLSv1.2 (IN),TLS 握手,服务器完成 (14): TLSv1.2 (OUT)、TLS 握手、客户端密钥交换 (16): TLSv1.2 (OUT),TLS 更改密码,客户端问候 (1): TLSv1.2 (OUT),TLS 握手,完成 (20): TLSv1.2 (IN),TLS 握手,完成 (20): 使用 TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 的 SSL 连接 ALPN,服务器不同意协议 服务器证书: 主题:OU=域控制已验证; OU=PositiveSSL 通配符; CN=*.example.com 开始日期:格林威治标准时间 2016 年 12 月 1 日 00:00:00 到期日期:格林威治标准时间 2019 年 12 月 1 日 23:59:59 subjectAltName:主机“example.com”匹配证书的“*.example.com” 发行人:C=GB; ST=大曼彻斯特; L=索尔福德; O=COMODO CA 有限公司; CN=COMODO RSA 域验证安全服务器 SSL 证书验证正常。 上传完全发送:64 个字节中的 64 个 TLSv1.2 (OUT)、TLS 警报、客户端问候 (1):【问题讨论】:
您的方法签名应如下所示:static async void Main(string[] args)
。您添加 async
关键字。
嗨@Stuart,那我不明白,因为当我更改 Main 方法时出现错误:程序不包含适合入口点的静态 Main 方法
您可能想要定义一个任务方法,然后从 Main... 中调用它...
@LukášVrábel 检查我的答案,这可能会解决您的问题。
【参考方案1】:
据我所知,您需要将用户名和密码转换为字节,并将其作为 base 64 字符串并将其传递给标题。当您使用 await 时,如果它是一个 void 方法,那么您应该在其签名中添加带有 Task 的 async 修饰符,或者如果该方法应该返回任何类型而不是使用 async Task ,如示例中所示。在这种情况下,您需要使用测试示例中所示的结果来获取结果。您可以在Microsoft docs 中阅读有关此主题的更多信息。
代码如下:
public async Task<HttpResponseMessage> CreateAuthorization(string url, string username, string password)
HttpResponseMessage response;
using (var httpClient = new HttpClient())
using (var request = new HttpRequestMessage(new HttpMethod("POST"), url))
request.Headers.TryAddWithoutValidation("Accept", "application/json");
var authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"username:password"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic authorization");
response = await httpClient.SendAsync(request);
return response;
这是测试它的示例:
public void CreateAuthorizationTest()
var response = CreateAuthorization("https://example.com", "username", "password");
var result = response.Result;
var o = result.Content.ReadAsStringAsync();
if (result.IsSuccessStatusCode)
//do some thing if success
// you can do deserialization what ever
Console.WriteLine(o);
else
//do some thing if error
Console.WriteLine(o);
//etc.
链接:
How and when to use ‘async’ and ‘await’ https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/【讨论】:
可以显示请求代码吗?这是有问题的帖子数据的传递。我也一直在使用application/x-www-form-urlencoded
。
@user1274820 只是为了确保另一个答案得到了赏金,所以我假设你得到了答案。所以我也假设我的回答是无关紧要的。如果您认为我可以贡献更多,请告诉我,以便我有空时可以查看它,现在是深夜在我的位置。
Wtf 我给了你赏金......你应该得到它,伙计
我开始了另一个赏金 - 我可以在 23 小时内奖励给你? 对不起那个人
没问题我很高兴你解决了它。祝你好运【参考方案2】:
使用本网站 https://curl.olsh.me/
using (var httpClient = new HttpClient())
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://example.com/"))
request.Headers.TryAddWithoutValidation("Accept", "application/json");
request.Content = new StringContent("\"username\":\"username\",\"password\":\"password\"", Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
【讨论】:
【参考方案3】:更新:
我收到了服务器的回复:
StatusCode:200,ReasonPhrase:'OK',版本:1.1,内容:System.Net.Http.StreamContent,标题: 日期:2018 年 9 月 25 日星期二 06:57:16 GMT 日期:2018 年 9 月 25 日星期二 06:57:17 GMT 连接:关闭 设置 Cookie:TS0119a36f=015d56898097bc7f5dccb374f352898f8806da5833c9f8a8ef4ff6ae2a2b1d4e78147fb79479f8bf85929406f34372c41c63572a89;路径=/;域=.example.com 传输编码:分块 内容类型:应用程序/json
我认为编码或 idk 存在一些问题。当我执行 curl 我得到这个输出(我需要的那个):
"code":200,"status":"success","sessionId":"350bf800-bfdb-11e8-991a-d35510009464"
当前代码:
static void Main(string[] args)
using (var httpClient = new HttpClient())
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.example.com"))
request.Headers.TryAddWithoutValidation("accept", "application/json");
request.Content = new StringContent("\"username\":\"user\",\"password\":\"pass\"", Encoding.UTF8, "application/json");
var task = httpClient.SendAsync(request);
task.Wait();
var response = task.Result;
Console.WriteLine(response);
Console.ReadKey();
【讨论】:
【参考方案4】:C# 7 中提供了异步主要方法。如果您使用的是早期版本,则可以像这样“手动”处理任务
var task = httpClient.SendAsync(request);
task.Wait();
var response = task.Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
【讨论】:
很不错,谢谢。我现在确实有来自服务器的响应,但遗憾的是我只看到了这个:StatusCode:200,ReasonPhrase:'OK',版本:1.1,内容:System.Net.Http.StreamContent,标题:哪里也应该是令牌,但我没看到。 实际上更具体地说,从 7.1 开始 @LukášVrábel 由于您收到 200 返回码,因此调用将通过服务器。如果您可以访问它以查看发生了什么,您可以尝试在服务器端进行调试。如果您无权访问服务器,您可以尝试让电话与 Postman 或类似的东西一起工作。 遗憾的是我无法访问该服务器。令牌的语法类似于:6fa3ea90-bc02-11e8-991a-d35512019464。这应该是编码的问题吧? 你能在你的问题中发布 curl 的输出吗?【参考方案5】:我使用 System.Net.Http.Formatting.Extension
示例:
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
// Add NuGet package System.Net.Http.Formatting.Extension
namespace SimpleRestCall
class Program
static CancellationTokenSource cts = new CancellationTokenSource();
static readonly string sitePath = "https://example.com";
static void Main(string[] args)
using (var client = new HttpClient BaseAddress = new Uri(sitePath), Timeout = new TimeSpan(0, 1, 0) )
Task.Run(() => Login(client)).Wait();
private static async Task Login(HttpClient client)
string path = ""; // if it's a controller path put it here
LoginData postData = new LoginData username = "username", password = "password" ;
string json;
using (HttpResponseMessage resp = await client.PostAsJsonAsync(path, postData, cts.Token))
json = await resp.Content.ReadAsStringAsync();
Console.WriteLine(json);
Console.WriteLine("Press a key to finish");
string aa = Console.ReadLine();
private class LoginData
public string username get; set;
public string password get; set;
【讨论】:
【参考方案6】:你要让main方法async
:
static async void Main(string[] args)
如果您使用的是 C# 版本 Main 中使用任何 await。在这种情况下,您必须为它定义一个Task
和.Wait()
(而不是为它定义await
)。
Task task = ....;
task.Wait();
var result = task.Result;
【讨论】:
以上是关于将 POST 卷曲到 C#的主要内容,如果未能解决你的问题,请参考以下文章