114 votes

Faire un appel cURL en C#

Je veux faire ce qui suit curl dans mon application console C# :

curl -d "text=This is a block of text" \
    http://api.repustate.com/v2/demokey/score.json

J'ai essayé de faire comme la question posée aquí mais je ne parviens pas à remplir correctement les propriétés.

J'ai également essayé de la convertir en une demande HTTP normale :

http://api.repustate.com/v2/demokey/score.json?text="This%20is%20a%20block%20of%20text"

Puis-je convertir un appel cURL en une requête HTTP ? Si oui, comment ? Sinon, comment puis-je effectuer correctement l'appel cURL ci-dessus à partir de mon application console C# ?

0 votes

1 votes

@DanielEarwicker : Je dirais que ce n'est pas le cas, seulement parce que HttpClient est dans le mélange maintenant, et il va être le site manière d'obtenir du contenu HTTP sur HttpWebRequest y WebClient à l'avenir.

175voto

casperOne Points 49736

Eh bien, vous n'appelleriez pas cURL directement, vous utiliserez plutôt l'une des options suivantes :

Je recommande vivement d'utiliser le HttpClient car elle est conçue pour être bien meilleure (du point de vue de la convivialité) que les deux premières.

Dans votre cas, vous feriez ceci :

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

Notez également que le HttpClient offre une bien meilleure prise en charge des différents types de réponses, ainsi qu'une meilleure prise en charge des opérations asynchrones (et de leur annulation) par rapport aux options mentionnées précédemment.

9 votes

J'ai essayé de suivre votre code pour un problème similaire mais je reçois des erreurs disant que await ne peut être défini que pour les méthodes asynchrones ?

0 votes

@Jay Oui, async et await sont une paire, vous ne pouvez pas utiliser l'un sans l'autre. Cela signifie que vous devez rendre asynchrone la méthode qui la contient (dont il n'y en a pas ici).

0 votes

Comment pourrais-je vérifier la réponse sans async ?

23voto

Thomas Points 1652

Ou dans 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);

6 votes

L'exemple d'utilisation de base ne fonctionne pas en dehors de la boîte. restSharp est de la camelote.

14voto

BenW Points 916

Vous trouverez ci-dessous un exemple de code fonctionnel.

Veuillez noter que vous devez ajouter une référence à 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();

Référence : TheDeveloperBlog.com

10voto

Tono Nam Points 4465

Réponse tardive mais c'est ce que j'ai fini par faire. Si vous voulez exécuter vos commandes curl de manière très similaire à ce que vous faites sous linux et que vous avez Windows 10 ou plus, faites ceci :

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

La raison pour laquelle le code est un peu long est que Windows vous donnera une erreur si vous exécutez un guillemet simple. En d'autres termes, la commande curl 'https://google.com' fonctionnera sous linux et ne fonctionnera pas sous Windows. Grâce à la méthode que j'ai créée, vous pouvez utiliser des guillemets simples et exécuter vos commandes curl exactement comme vous les exécutez sous linux. Ce code vérifie également les caractères d'échappement tels que \' y \" .

Par exemple, utilisez ce code comme

var output = ExecuteCurl(@"curl 'https://google.com' -H 'Accept: application/json, text/javascript, */*; q=0.01'");

Si tu veux utiliser cette même chaîne contre C:\Windows\System32\curl.exe cela ne fonctionnera pas car, pour une raison quelconque, Windows n'aime pas les guillemets simples.

6voto

Bob Points 323

Je sais qu'il s'agit d'une question très ancienne mais je poste cette solution au cas où elle aiderait quelqu'un. J'ai récemment rencontré ce problème et google m'a conduit ici. La réponse ici m'aide à comprendre le problème mais il y a encore des problèmes dus à ma combinaison de paramètres. Ce qui résout finalement mon problème est convertisseur curl vers C# . C'est un outil très puissant qui prend en charge la plupart des paramètres de Curl. Le code qu'il génère est presque immédiatement exécutable.

10 votes

Je ferais très attention à ne pas y coller de données sensibles (comme les cookies d'authentification)...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X