C # में CURL कॉल करना


88

मैं 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अब मिश्रण में है, और यह HTTP सामग्री को प्राप्त करने और आगे बढ़ने का मार्ग बनने जा रहा है। HttpWebRequestWebClient
कास्परऑन

जवाबों:


146

ठीक है, आप सीधे 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
मैंने इसी तरह के मुद्दे के लिए आपके कोड का अनुसरण करने की कोशिश की है, लेकिन मुझे ऐसी त्रुटियां दी जा रही हैं, जिनका इंतजार केवल async तरीकों से किया जा सकता है?
Jay

@ जय हाँ, async और प्रतीक्षा एक जोड़ी है, आप एक दूसरे के बिना उपयोग नहीं कर सकते। इसका मतलब है कि आपको युक्त विधि (जिसमें से यहाँ कोई नहीं है) को async करना होगा।
कैस्पर ओने

1
@Jay उन तरीकों में से अधिकांश Task<T>, आप बस उपयोग नहीं कर सकते हैं asyncऔर फिर सामान्य रूप से रिटर्न प्रकारों के साथ सौदा कर सकते हैं (आपको कॉल करना होगा Task<T>.Result। ध्यान दें, आप उपयोग करने में बेहतर हैं, asyncहालांकि आप परिणाम के लिए इंतजार कर रहे धागे को बर्बाद कर रहे हैं।
19

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
मरे हार्ट

24

या विश्रामशाला में :

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 कबाड़ है।
एलेक्स जी

1
@ एलेक्स जी आप इसे गलत कर रहे हैं। मेरे लिये कार्य करता है।
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


2

देर से प्रतिक्रिया लेकिन यह वही है जो मैंने किया। यदि आप अपने कर्ल कमांड को उसी तरह चलाना चाहते हैं जैसे आप उन्हें लिनक्स पर चलाते हैं और आपके पास विंडोज़ 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'लिनक्स पर काम करेगा और यह विंडोज़ पर काम नहीं करेगा। उस विधि के लिए धन्यवाद, मैंने बनाया आप एकल उद्धरणों का उपयोग कर सकते हैं और अपने कर्ल कमांड को ठीक वैसे ही चला सकते हैं जैसे आप उन्हें लिनक्स पर चलाते हैं। यह कोड इस तरह के \'और भागने के पात्रों के लिए भी जाँच करता है \"

उदाहरण के लिए इस कोड का उपयोग करें

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

यदि आप जहां उसी स्ट्रिंग को फिर से चलाना चाहते हैं तो C:\Windows\System32\curl.exeयह काम नहीं करेगा क्योंकि किसी कारण से विंडोज़ एकल उद्धरण पसंद नहीं करता है।


2

मुझे पता है कि यह एक बहुत पुराना सवाल है लेकिन मैं इस समाधान को पोस्ट करता हूं अगर यह किसी की मदद करता है। मैंने हाल ही में इस समस्या से मुलाकात की और Google ने मुझे यहां पहुंचाया। यहाँ जवाब मुझे समस्या को समझने में मदद करता है लेकिन मेरे पैरामीटर संयोजन के कारण अभी भी समस्याएँ हैं। आखिरकार मेरी समस्या का हल C # कनवर्टर के लिए कर्ल है । यह एक बहुत शक्तिशाली उपकरण है और कर्ल के अधिकांश मापदंडों का समर्थन करता है। यह उत्पन्न कोड लगभग तुरंत चलने योग्य है।


2
मैं वहाँ किसी भी संवेदनशील डेटा (जैसे कि कुकीज़) को चिपकाने के लिए सावधान रहना चाहूंगा ...
आदि एच 14

0

अपने कंसोल ऐप से कॉल कुर्ल एक अच्छा विचार नहीं है।

लेकिन आप TinyRestClient का उपयोग कर सकते हैं जो अनुरोध बनाने में आसान बनाते हैं:

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

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

0

यदि आप सेमी # लाइन एक्सप के साथ सी # के लिए नए हैं। आप " https://curl.olsh.me/ " जैसी ऑनलाइन साइटों का उपयोग कर सकते हैं या कर्ल को C # कनवर्टर में खोज सकते हैं, जो आपके लिए ऐसा कर सकता है।

या यदि आप पोस्टमैन का उपयोग कर रहे हैं, तो आप जेनरेट कोड स्निपेट का उपयोग कर सकते हैं केवल पोस्टमैन कोड जनरेटर के साथ समस्या रेस्टसैप्ड लाइब्रेरी पर निर्भरता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.