c#错误请求中的cURL调用

时间:2018-12-17 09:23:05

标签: c# .net curl dotnet-httpclient

我正在尝试在c#.net环境中进行以下cURL调用

curl -XPOST -d 'Metadata/Type = "sas"' http://bms.org/bcknd/republish

C#代码如下:

var requestContent = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Metadata/Type", "\"sas\""), });
HttpResponseMessage response = await client.PostAsync("http://bms.org/bcknd/republish", requestContent);
HttpContent responseContent = response.Content;

using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
            Console.WriteLine(await reader.ReadToEndAsync());
}

我收到一个400错误的请求,并且在我打印出来时。也许与curl调用中的-XPOST和-d参数有关?

编辑: 这是curl的http请求:

POST http://bms.org/bcknd/republish HTTP/1.1
Host: bms.org/bcknd
User-Agent: curl/7.48.0
Accept: */*
Content-Length: 43
Content-Type: application/x-www-form-urlencoded

Metadata/Type = "sas"

这是我的代码中的http请求:

POST http://bms.org/bcknd/republish HTTP/1.1
Accept: */*
User-Agent: curl/7.48.0
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: bms.org/bcknd
Content-Length: 43
Connection: Keep-Alive

Metadata/Type = "sas"

2 个答案:

答案 0 :(得分:1)

简短版本

不使用url编码将数据发布为StringContent,并在尝试读取响应正文之前检查响应状态。 确保调用在应用程序退出之前完成,否则在应用程序退出时呼叫将被取消。也就是说,请在async Task中使用Main,而不要使用async void

class Program
{
    static async Task Main(string[] args)
    {
        var client=new HttpClient();
        var data = new StringContent("Metadata/Type=\"sas\"",Encoding.UTF8,"application/x-www-form-urlencoded");
        var response = await client.PostAsync("http://www.google.com/bcknd/republish", data);
        if(response.IsSuccessStatusCode)
        {
            var  responseContent = response.Content;
            var body=await response.Content.ReadAsStringAsync();
            Console.WriteLine(body);
        }
        else 
        {
            Console.WriteLine($"Oops! {response.StatusCode} - {response.ReasonPhrase}");
        }
    }
}

说明

在这种情况下,了解实际发送的内容非常重要。为此,可以使用Fiddler或Charles之类的调试代理。

使用-d进行卷曲会发送未编码的数据。这个电话:

curl -XPOST -d 'Metadata/Type = "sas"' http://bms.org/bcknd/republish

将发送:

POST http://www.google.com/bcknd/republish HTTP/1.1
Host: www.google.com
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Content-Length: 21
Content-Type: application/x-www-form-urlencoded

Metadata/Type = "sas"
如果应用了URL编码,则

/"将被其他字符替换。另请注意User-AgentAccept标头

如果使用--data-urlencode,则该值将经过URL编码:

POST http://www.google.com/bcknd/republish HTTP/1.1
Host: www.google.com
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

Metadata/Type =%20%22sas%22

另一方面,此代码:

static async Task Main(string[] args)
{
    var client=new HttpClient();
    var data = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Metadata/Type", "\"sas\""), });
    var response = await client.PostAsync("http://www.google.com/bcknd/republish", data);
    var  responseContent = response.Content;
    var body=await response.Content.ReadAsStringAsync();
    Console.WriteLine(body);
}

将发送:

POST http://www.google.com/bcknd/republish HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Host: www.google.com

Metadata%2FType=%22sas%22

要获得原始有效载荷,可以将StringContent与手工编码的内容一起使用:

var data = new StringContent("Metadata/Type= \"sas\"",Encoding.UTF8,"application/x-www-form-urlencoded");

请求是:

POST http://www.google.com/bcknd/republish HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 19
Host: www.google.com

Metadata/Type= "sas"

如果要发送User-AgentAccept标头,则可以将它们添加到每条消息中或作为默认请求标头:

var client=new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("curl","7.55.1"));

这些将添加:

Accept: */*
User-Agent: curl/7.55.1

针对请求

答案 1 :(得分:0)

您可以使用HttpClient

如下调用远程URL。
using (var httpClient = new HttpClient())
{
    using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://bms.org/bcknd/republish"))
    {
        request.Content = new StringContent("Metadata/Type = \"sas\"", Encoding.UTF8, "application/x-www-form-urlencoded");

        var response = await httpClient.SendAsync(request);
    }
}

在这里,我刚刚添加了参考代码,使用它可以创建自己的参考代码。我检查了您的卷曲请求和it seems issue it self