在 C # 中进行 cURL 调用

我想在我的 C # 控制台应用中做以下的 curl调用:

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 请求吗?如果是这样,怎么做?如果没有,我怎样才能正确地从我的 C # 控制台应用调用上面的 cURL?

283061 次浏览

Well, you wouldn't call cURL directly, rather, you'd use one of the following options:

I'd highly recommend using the HttpClient class, as it's engineered to be much better (from a usability standpoint) than the former two.

In your case, you would do this:

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

Also note that the HttpClient class has much better support for handling different response types, and better support for asynchronous operations (and the cancellation of them) over the previously mentioned options.

Below is a working example code.

Please note you need to add a reference to 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();

Reference: TheDeveloperBlog.com

Or in 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);

Call cURL from your console app is not a good idea.

But you can use TinyRestClient which make easier to build requests :

var client = new TinyRestClient(new HttpClient(),"https://api.repustate.com/");


client.PostRequest("v2/demokey/score.json").
AddQueryParameter("text", "").
ExecuteAsync<MyResponse>();

Late response but this is what I ended up doing. If you want to run your curl commands very similarly as you run them on linux and you have windows 10 or latter do this:

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

The reason why the code is a little bit long is because windows will give you an error if you execute a single quote. In other words, the command curl 'https://google.com' will work on linux and it will not work on windows. Thanks to that method I created you can use single quotes and run your curl commands exactly as you run them on linux. This code also checks for escaping characters such as \' and \".

For example use this code as

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

If you where to run that same string agains C:\Windows\System32\curl.exe it will not work because for some reason windows does not like single quotes.

I know this is a very old question but I post this solution in case it helps somebody. I recently met this problem and google led me here. The answer here helps me to understand the problem but there are still issues due to my parameter combination. What eventually solves my problem is curl to C# converter. It is a very powerful tool and supports most of the parameters for Curl. The code it generates is almost immediately runnable.

Well if you are new to C# with cmd-line exp. you can use online sites like "https://curl.olsh.me/" or search curl to C# converter will returns site that could do that for you.

or if you are using postman you can use Generate Code Snippet only problem with Postman code generator is the dependency on RestSharp library.

Don't forget to add System.Net.Http, specially if you receive this error:

Severity Code Description Project File Line Suppression State Error CS0246 The type or namespace name 'HttpClient' could not be found (are you missing a using directive or an assembly reference?) 1_default.aspx D:\Projetos\Testes\FacebookAPI\FB-CustomAudience\default.aspx.cs 56 Active

In this case you shoud:

  1. Add System.Net.Http from Nuget: Tools / NuGet Package Manager / Manager NuGet Packages for Solution;
  2. Search for System.Net.Http
  3. Add in the top of your page the follow code: using System.Net.Http;