C++/CLR post HTTP

Alexandru Teodor 91 Reputation points
2022-06-10T08:39:51.47+00:00

Hello all,

Using Visual Studio 2019 I am trying to write a small windows desktop application with C++ CLR (.NET Framework).

After a lot of trial an error I managed to get a HTTP GET request working.

    System::String^ HTTP_GET(System::String^ link) {  
    		System::Net::HttpWebRequest^ request = dynamic_cast<System::Net::HttpWebRequest^>(System::Net::WebRequest::Create(link));  
    		System::Net::HttpWebResponse^ response = dynamic_cast<System::Net::HttpWebResponse^>(request->GetResponse());  
    		Stream^ dataStream = response->GetResponseStream();  
    		StreamReader^ reader = gcnew StreamReader(dataStream);  
    		System::String^ responseFromServer = reader->ReadToEnd();  
    		response->Close();  
    		return System::Convert::ToString(responseFromServer);  
    	}  
  
  

Having no experience in C++, I spend almost 2 days trying to build the POST equivalent (based on what i have found online) with no success. Here is what I managed to build so far:

	System::String^ HTTP_POST(System::String^ link, System::String^ param) {  
		array<Byte>^ buffer = Encoding::UTF8->GetBytes(param); // <== error: too few arguments for class template "std::array"  
		System::Net::HttpWebRequest^ request = dynamic_cast<System::Net::HttpWebRequest^>(System::Net::WebRequest::Create(link));  
		request->Method = "POST";  
		System::IO::Stream^ stream = request->GetRequestStream();  
		stream->Write(buffer, 0, buffer->Length);  
		stream->Flush();  
		stream->Close();  
  
		//read the response  
		System::Net::HttpWebResponse^ response = dynamic_cast<System::Net::HttpWebResponse^>(request->GetResponse());  
		Stream^ dataStream = response->GetResponseStream();  
		StreamReader^ reader = gcnew StreamReader(dataStream);  
		System::String^ responseFromServer = reader->ReadToEnd();  
		response->Close();  
		return System::Convert::ToString(responseFromServer);  
	}  

The following line is blocking me as I have no ideea how to correct it.

array<Byte>^ buffer = Encoding::UTF8->GetBytes(param);  

If I change the line to:

array<Byte,1>^ buffer = Encoding::UTF8->GetBytes(param);  

i get the error: a handle to a non-managed class is not allowed.

If I chanage the line to:

System: Array^ buffer = Encoding::UTF8->GetBytes(param);  

Then the line:

stream->Write(buffer, 0, buffer->Length);  

Errors with: function "System::IO::Stream::Write" cannot be called with the given argument list
function type is IO::Stream^ but arguments are System::Array^, int, int ...

Can anyone help me with fixing the code so that will POST and retrive the response from server?

Thank you.

P.S: I also tried with curl but again, with no success in resolving the error I get and retreving the response:

static size_t Callback(void* contents, size_t size, size_t nmemb, std::string* userp) {  
	userp->append((char*)contents, size * nmemb);  
	return size * nmemb;  
}  

CURL* curl;  
CURLcode res;  
curl_global_init(CURL_GLOBAL_ALL);  

curl = curl_easy_init();  
if (curl) {  
	string readBuffer{};  
	  
	curl_easy_setopt(curl, CURLOPT_URL, "https://some-link/test-post.php");  
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "param=something");  
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Callback); // <== error: can't take address of 'CLRproject::MyForm::Callback' unless creating delegate instance  
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, readBuffer);  

	res = curl_easy_perform(curl);  

	if (res != CURLE_OK)  
		label2->Text = System::Convert::ToString(curl_easy_strerror(res));  

	curl_easy_cleanup(curl);  
	//System::String^ x = gcnew System::String(readBuffer.data());  
	label2->Text = System::Convert::ToString(curl_easy_strerror(res));  
}  
curl_global_cleanup();	  
Developer technologies C++
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 122.5K Reputation points
    2022-06-10T08:47:23.25+00:00

    To solve the compilation problem, try this:

    cli::array<Byte>^ buffer = Encoding::UTF8->GetBytes( param );  
    
    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Alexandru Teodor 91 Reputation points
    2022-06-10T09:09:09.817+00:00

    Thanks Viorel!

    Changing to that line indeed solved the compilation problem (thank you so much for that!!!), but this revealed a new problem:

    The post parameter "param" supplied to the function is a string formated as "key1=value1&key2=value2", but for some reason it is not processed server side.
    It seems the server does not see the parameter keys.

    I don't know if my code is wrong and does not send to server the parameters... (post is processed as i get a result from the server as if no parameter was sent)


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.