C #에서 cURL 호출 만들기


89

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 요청으로 변환 할 수 있습니까? 그렇다면 어떻게? 그렇지 않은 경우 C # 콘솔 애플리케이션에서 위의 cURL 호출을 올바르게 수행하려면 어떻게해야합니까?



@DanielEarwicker : 나는 그것 때문이 아니다라고 말하고 싶지만 HttpClient지금은 혼합에, 그것은 될 것 GET HTTP를 통해 콘텐츠에 대한 방법 과 앞으로. HttpWebRequestWebClient
casperOne 2011 년

답변:


147

음, cURL을 직접 호출하지 않고 다음 옵션 중 하나를 사용합니다.

나는 사용을 적극 권장합니다 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클래스는 이전에 언급 한 옵션보다 다양한 응답 유형을 처리하는 데 훨씬 더 나은 지원을 제공하고 비동기 작업 (및 취소)을 더 잘 지원합니다.


7
비슷한 문제에 대해 귀하의 코드를 따르려고 시도했지만 await는 비동기 메서드로만 설정할 수 있다는 오류가 발생합니까?
Jay

@Jay 예, async와 await는 쌍입니다. 다른 하나 없이는 사용할 수 없습니다. 즉, 포함하는 메서드 (여기에는 없음)를 비동기로 만들어야합니다.
casperOne 2013-09-27

1
@Jay 대부분의 메소드는 return을 Task<T>사용하지 않고 async일반적으로 반환 유형을 처리 할 수 있습니다 (를 호출해야합니다 Task<T>.Result. 참고, async결과를 기다리는 스레드를 낭비하므로 사용하는 것이 좋습니다 .
casperOne 2013-09-29

1
예 @Maxsteel, 그것의 배열이다 KeyValuePair<string, string>그냥 사용합니다 그래서는new [] { new KeyValuePair<string, string>("text", "this is a block of text"), new KeyValuePair<string, string>("activity[verb]", "testVerb") }
casperOne

1
이렇게 전화를 걸 때이 기능이 작동 할 수 있습니까? curl -k -i -H "Accept: application/json" -H "X-Application: <AppKey>" -X POST -d 'username=<username>&password=<password>' https://identitysso.betfair.com/api/login
Murray Hart

25

또는 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);

1
기본 사용 예제는 즉시 작동하지 않습니다. restSharp는 정크입니다.
Alex G

1
@AlexG 당신은 잘못하고 있습니다. 나를 위해 작동합니다.
user2924019

13

아래는 작동하는 예제 코드입니다.

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


3

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 누군가에게 도움이 될 경우이 솔루션을 게시합니다. 나는 최근 에이 문제를 만났고 Google이 나를 여기로 인도했습니다. 여기에 대한 대답은 문제를 이해하는 데 도움이되지만 매개 변수 조합으로 인해 여전히 문제가 있습니다. 결국 내 문제를 해결하는 것은 curl to C # converter 입니다. 이것은 매우 강력한 도구이며 Curl에 대한 대부분의 매개 변수를 지원합니다. 생성되는 코드는 거의 즉시 실행 가능합니다.


3
민감한 데이터 (예 : 인증 쿠키)를 여기에 붙여 넣지 않도록 조심해야합니다.
Adi H

2

응답이 늦었지만 이것이 내가 한 일입니다. Linux에서 실행하는 것과 매우 유사하게 curl 명령을 실행하고 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에서는 작동하지 않습니다. 내가 만든 그 방법 덕분에 작은 따옴표를 사용하고 Linux에서 실행하는 것과 똑같이 curl 명령을 실행할 수 있습니다. 이 코드는 또한 \'및 같은 이스케이프 문자를 확인합니다.\" .

예를 들어이 코드를 다음과 같이 사용하십시오.

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

같은 문자열을 어디에서 다시 실행하면 C:\Windows\System32\curl.exe어떤 이유로 창은 작은 따옴표를 좋아하지 않기 때문에 작동하지 않습니다.


0

콘솔 앱에서 cURL을 호출하는 것은 좋은 생각이 아닙니다.

그러나 TinyRestClient 를 사용하면 요청을 더 쉽게 작성할 수 있습니다 .

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

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

0

cmd-line exp로 C #을 처음 사용하는 경우. " https://curl.olsh.me/ 와 같은 온라인 사이트를 사용할 수 있습니다. " 또는 C # 변환기로 curl을 검색하면이를 수행 할 수있는 사이트가 반환됩니다.

또는 postman을 사용하는 경우 Generate Code Snippet을 사용할 수 있습니다. Postman 코드 생성기의 문제는 RestSharp 라이브러리에 대한 종속성입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.