Выполнение вызова cURL в C#
Я хочу сделать следующий вызов curl в моем консольном приложении C#:
curl -d "text=This is a block of text"
http://api.repustate.com/v2/demokey/score.json
Я пытался сделать как вопрос, размещенный здесь, но я не могу заполнить свойства правильно.
Я также попытался преобразовать его в обычный HTTP-запрос:
http://api.repustate.com/v2/demokey/score.json?text="This%20is%20a%20block%20of%20text"
Могу ли я преобразовать вызов cURL в запрос HTTP? Если так, то как? Если нет, как я могу правильно выполнить вышеуказанный вызов cURL из моего консольного приложения C#?
9 ответов
Ну, вы бы не вызывали cURL напрямую, скорее, вы бы использовали один из следующих вариантов:
HttpWebRequest
/HttpWebResponse
WebClient
HttpClient
(доступно с версии.NET 4.5)
Я очень рекомендую использовать HttpClient
класс, так как он спроектирован, чтобы быть намного лучше (с точки зрения удобства использования), чем первые два.
В вашем случае вы бы сделали это:
using System.Net.Http;
var client = new HttpClient();
// Create the HttpContent for the form to be posted.
var requestContent = new FormUrlEncodedContent(new [] {
new KeyValuePair<string, string>("text", "This is a block of text"),
});
// Get the response.
HttpResponseMessage response = await client.PostAsync(
"http://api.repustate.com/v2/demokey/score.json",
requestContent);
// Get the response content.
HttpContent responseContent = response.Content;
// Get the stream of the content.
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
// Write the output.
Console.WriteLine(await reader.ReadToEndAsync());
}
Также обратите внимание, что HttpClient
Класс имеет гораздо лучшую поддержку для обработки различных типов ответов и лучшую поддержку для асинхронных операций (и их отмены) по сравнению с ранее упомянутыми опциями.
Или в restSharp:
var client = new RestClient("https://example.com/?urlparam=true");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("header1", "headerval");
request.AddParameter("application/x-www-form-urlencoded", "bodykey=bodyval", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Ниже приведен пример рабочего кода.
Обратите внимание, что вам нужно добавить ссылку на Newtonsoft.Json.Linq
string url = "https://yourAPIurl"
WebRequest myReq = WebRequest.Create(url);
string credentials = "xxxxxxxxxxxxxxxxxxxxxxxx:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
CredentialCache mycache = new CredentialCache();
myReq.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
WebResponse wr = myReq.GetResponse();
Stream receiveStream = wr.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
Console.WriteLine(content);
var json = "[" + content + "]"; // change this to array
var objects = JArray.Parse(json); // parse as array
foreach (JObject o in objects.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
string name = p.Name;
string value = p.Value.ToString();
Console.Write(name + ": " + value);
}
}
Console.ReadLine();
Ссылка: TheDeveloperBlog.com
Поздний ответ, но это то, чем я закончил. Если вы хотите запускать свои команды curl так же, как вы запускаете их в linux, и у вас Windows 10 или более поздняя версия, сделайте следующее:
public static string ExecuteCurl(string curlCommand, int timeoutInSeconds=60)
{
if (string.IsNullOrEmpty(curlCommand))
return "";
curlCommand = curlCommand.Trim();
// remove the curl keworkd
if (curlCommand.StartsWith("curl"))
{
curlCommand = curlCommand.Substring("curl".Length).Trim();
}
// this code only works on windows 10 or higher
{
curlCommand = curlCommand.Replace("--compressed", "");
// windows 10 should contain this file
var fullPath = System.IO.Path.Combine(Environment.SystemDirectory, "curl.exe");
if (System.IO.File.Exists(fullPath) == false)
{
if (Debugger.IsAttached) { Debugger.Break(); }
throw new Exception("Windows 10 or higher is required to run this application");
}
// on windows ' are not supported. For example: curl 'http://ublux.com' does not work and it needs to be replaced to curl "http://ublux.com"
List<string> parameters = new List<string>();
// separate parameters to escape quotes
try
{
Queue<char> q = new Queue<char>();
foreach (var c in curlCommand.ToCharArray())
{
q.Enqueue(c);
}
StringBuilder currentParameter = new StringBuilder();
void insertParameter()
{
var temp = currentParameter.ToString().Trim();
if (string.IsNullOrEmpty(temp) == false)
{
parameters.Add(temp);
}
currentParameter.Clear();
}
while (true)
{
if (q.Count == 0)
{
insertParameter();
break;
}
char x = q.Dequeue();
if (x == '\'')
{
insertParameter();
// add until we find last '
while (true)
{
x = q.Dequeue();
// if next 2 characetrs are \'
if (x == '\\' && q.Count > 0 && q.Peek() == '\'')
{
currentParameter.Append('\'');
q.Dequeue();
continue;
}
if (x == '\'')
{
insertParameter();
break;
}
currentParameter.Append(x);
}
}
else if (x == '"')
{
insertParameter();
// add until we find last "
while (true)
{
x = q.Dequeue();
// if next 2 characetrs are \"
if (x == '\\' && q.Count > 0 && q.Peek() == '"')
{
currentParameter.Append('"');
q.Dequeue();
continue;
}
if (x == '"')
{
insertParameter();
break;
}
currentParameter.Append(x);
}
}
else
{
currentParameter.Append(x);
}
}
}
catch
{
if (Debugger.IsAttached) { Debugger.Break(); }
throw new Exception("Invalid curl command");
}
StringBuilder finalCommand = new StringBuilder();
foreach (var p in parameters)
{
if (p.StartsWith("-"))
{
finalCommand.Append(p);
finalCommand.Append(" ");
continue;
}
var temp = p;
if (temp.Contains("\""))
{
temp = temp.Replace("\"", "\\\"");
}
if (temp.Contains("'"))
{
temp = temp.Replace("'", "\\'");
}
finalCommand.Append($"\"{temp}\"");
finalCommand.Append(" ");
}
using (var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "curl.exe",
Arguments = finalCommand.ToString(),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = Environment.SystemDirectory
}
})
{
proc.Start();
proc.WaitForExit(timeoutInSeconds*1000);
return proc.StandardOutput.ReadToEnd();
}
}
}
Причина, по которой код немного длиннее, заключается в том, что окна выдадут вам ошибку, если вы выполните одиночную кавычку. Другими словами, командаcurl 'https://google.com'
будет работать в Linux и не будет работать в Windows. Благодаря этому методу, который я создал, вы можете использовать одинарные кавычки и запускать свои команды curl точно так же, как вы запускаете их в Linux. Этот код также проверяет наличие экранирующих символов, таких как\'
а также \"
.
Например, используйте этот код как
var output = ExecuteCurl(@"curl 'https://google.com' -H 'Accept: application/json, text/javascript, */*; q=0.01'");
Если вы снова запустите ту же строку C:\Windows\System32\curl.exe
это не сработает, потому что по какой-то причине Windows не любит одинарные кавычки.
Я знаю, что это очень старый вопрос, но я публикую это решение на случай, если оно кому-то поможет. Я недавно столкнулся с этой проблемой, и Google привел меня сюда. Ответ здесь помогает мне понять проблему, но все еще есть проблемы из-за моей комбинации параметров. Что в конечном итоге решает мою проблему, так это преобразователь curl в C#. Это очень мощный инструмент, поддерживающий большинство параметров Curl. Код, который он генерирует, запускается практически сразу.
Не забудьте добавить System.Net.Http, особенно если вы получаете эту ошибку:
Код серьезности Описание Ошибка состояния подавления строки файла проекта CS0246 Не удалось найти тип или имя пространства имен «HttpClient» (вы пропустили директиву using или ссылку на сборку?) 1_default.aspx D:\Projetos\Testes\FacebookAPI\FB-CustomAudience\default.aspx.cs 56 Активный
В этом случае вы должны:
- Добавьте System.Net.Http из Nuget: Инструменты/Диспетчер пакетов NuGet/Диспетчер пакетов NuGet для решения;
- Найдите System.Net.Http
- Добавьте в начало страницы следующий код:using System.Net.Http;
Хорошо, если вы новичок в C# с cmd-line exp. вы можете использовать такие онлайн-сайты, как " https://curl.olsh.me/", или поисковый преобразователь curl в C# вернет сайт, который может сделать это за вас.
или если вы используете почтальона, вы можете использовать "Создать фрагмент кода", только проблема с генератором кода почтальона - это зависимость от библиотеки RestSharp.
В 2023 году нам фактически придется вызывать Curl напрямую, потому что любой другой метод использует внутренний веб-клиент Windows, который является старым и бесполезным и выдает сообщение «Не удалось создать безопасный канал SSL/TLS». В Windows Server 2012 R2 отсутствуют наборы шифров и нет возможности установить новые. .
- загрузите CURL с https://curl.se/windows/
- распаковать папку /bin в папку PathToCurl
- из .net-звонка
System.Diagnostics.Process.Start("X:\\PathToCurl\\curl.exe", "-d \"text=This is a block of text\" http://api.repustate.com/v2/demokey/score.json").WaitForExit();
Вызывать cURL из консольного приложения не очень хорошая идея.
Но вы можете использовать TinyRestClient, который упрощает создание запросов:
var client = new TinyRestClient(new HttpClient(),"https://api.repustate.com/");
client.PostRequest("v2/demokey/score.json").
AddQueryParameter("text", "").
ExecuteAsync<MyResponse>();