вызов cURL в c # неверный запрос - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь выполнить следующий вызов cURL в среде ac # .net

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Плохой запрос и когда я его распечатаю.Может быть, это как-то связано с параметрами -XPOST и -d из вызова curl?

РЕДАКТИРОВАТЬ: Вот http-запрос из curl:

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 голосов
/ 17 декабря 2018

Короткая версия

Отправьте данные как StringContent без кодировки URL и проверьте состояние ответа, прежде чем пытаться прочитать тело ответа. Убедитесь, что вызов завершен до выхода из приложения, в противном случае вызов будет отменен при выходе из приложения.Это означает, что используйте 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.

Curl с -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-Agent и Accept

Если используется --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-Agent и Accept, вы можете добавить их к каждому отдельному сообщению или в качестве заголовков запроса по умолчанию:

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

на запрос

0 голосов
/ 17 декабря 2018

Вы можете вызвать удаленный URL следующим образом, используя HttpClient

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);
    }
}

Здесь я только что добавил ссылочный код, с помощью которого вы можете создать свой собственный.Я проверил ваш запрос керлинга и кажется, что выдает его самостоятельно .

...