Getting the Right Syntax for uploading a file using the exe. of the code below

Jan 7, 2015 at 8:57 PM
Edited Jan 7, 2015 at 8:58 PM
I am trying to call the exe. part of this program from another program to upload an XML file to a server. The XML file to be uploaded will be set once it is created. I am having issue with the syntax at the client.request section. Could you please help me out. Maybe my program could be done better, please advice as I am still a novice programmer.
The code is below:
int _tmain(int argc, _TCHAR* argv[])

{
if(argc < 2)
{
    cout << "Error: Not enough parameters!";
    return 0;
}

auto stream = concurrency::streams::file_buffer<string_t>::open(argv[1], std::ios_base::in).get();

if(stream == NULL)
{
    cout << "Error: No such file!";
    return 0;
}


http_client client (U("my server"));
// error at the: = client.request part
http_response response = client.request(methods::POST, U("path"), stream, U("string_t")).get();
if(response.status_code() == status_codes::OK)
{
    const utility::string_t body = response.extract_string().get();
    std::wcout<<body;
}

//getchar();

return 0;
}

Thanks,

Steven
Coordinator
Jan 8, 2015 at 2:31 AM
Hi Steven,

In the future please post what the compilation error message is that you are getting, it certainly would help a lot more in understanding the problem. Here are a couple of things I notice:
  • Not sure why you are checking if the stream is NULL? It is a class object and never will be NULL. If the file_buffer::open function fails it will throw an exception out of the task it returns.
  • The http_client::request(...) method takes a stream of character type uint8_t and you have a stream of string_t. These are different sizes and there for different types. Instead you should use a stream of uint8_t:
auto stream = concurrency::streams::file_buffer<uint8_t>::open(argv[1], std::ios_base::in).get();
  • I'm pretty sure you don't want to use a Content-Type of 'string_t' for your HTTP request. What is the type of the data you want to send?
Steve
Jan 8, 2015 at 4:22 PM
Hi Steve,

Thanks again for your speedy response, will look to add error messages next time I ask questions. I changed the code and there are currently no errors.
However this issue I am having is that when I manually give the the code below an XML file with string data type, it updates it to the server. However when I use the exe. from this code and call it in another program, which where I want to use it, it does not update the data to the server.
My objective is automate to xml file data generated from a test in the other program to a server. So i will like to call the exe once the XML is generated before the program is done. Below is the code for the exe.:

int _tmain(int argc, _TCHAR* argv[])

{
if(argc < 2)
{
    cout << "Error: Not enough parameters!";
    return 0;
}

auto stream = concurrency::streams::file_buffer<uint8_t>::open(argv[1], std::ios_base::in).get();

http_client client (U("My SERVER ADDRESS"));

http_response response = client.request(methods::POST, U("path"), stream, U("string_t")).get();
if(response.status_code() == status_codes::OK)
{
    const utility::string_t body = response.extract_string().get();
    std::wcout<<body;
}

return 0;
}

The code I use to call the exe in the other program is:

system ("uploadXMLfiletoserver.exe ") +XML filename ";

I will have just doen this with all in the main program, but as it does not support REST SDK, i get this error below when i tried,

error C1189: #error : <atomic> is not supported when compiling with /clr or /clr:pure.

I am now trying to just call the exe. from the program that it works with and feed the exe an xml file to upload to a sever.

I hope my question is clear enough, I am still trying to improve my programming skiils so please bear with me if my question is not the brightest.

Thanks and hope to hear from you soon.

Regards,

Steven
Coordinator
Jan 8, 2015 at 5:49 PM
Hi Steven,

I don't really understand exactly what you are talking about, what happens when you launch the executable from another program? I'm not seeing what the error or problem is. The error you mention about with std::atomic, you asked a discussion thread in the past about this, the C++ Rest SDK will not work under C++/CLI. Also if you are just writing this to call from another program you probably would be better off creating a dll, exporting an API for it and calling from your program.

Steve
Marked as answer by roschuma on 1/26/2015 at 1:53 PM
Jan 8, 2015 at 6:29 PM
Hi Steve,

What I am trying to do is upload an XML file to a server from a C++/CLI program which creates the XML file. I think my issue with why the file is not uploaded is because I am calling the uploading program's exe (which uses Rest SDK) from a C++/CLI program. Thank for your advice and I will look to create a dll, export an API for it and call it from my program.

Thanks,

Steven
Jan 21, 2015 at 7:48 PM
Hi Steve,

I am trying call an exe. program that uses Casablanca to upload XML data to a server. When I call it i get this System error pop up

" The program cannot start because ccprest110d_2_3.dll is missing from your computer. Try re installing the program to fix this problem. "

I cannot find this dll from my Casablanca library. Am i to install it in the folder that I am calling the exe. from.

Thanks,

-Steven
Coordinator
Jan 21, 2015 at 10:01 PM
Hi Steven,

You need to deploy the C++ REST SDK dlls with your application. You can build the dlls from source or use them from our NuGet package. Once you install the NuGet package you can find the dlls under the packages folder in your solution under the correct toolset, platform, and configuration.

Steve
Marked as answer by roschuma on 1/26/2015 at 1:53 PM
Jan 22, 2015 at 1:35 PM
Thank you Steve
Jan 27, 2015 at 8:27 PM
Hi Steve,

Last question i hope......with the code below, I connect to a server and upload the data I want. However upon running the program for the first time it gives me a "debug error R6010" then when I close it and do nothing but run it again, it works with no issues. Could you help me out with troubleshooting this because my end application is an automation with no option for the user to re run the program if it fails on the first run. Code is:

int _tmain(int argc, _TCHAR* argv[])
{
auto stream = concurrency::streams::file_buffer<uint8_t>::open(U("content being uploaded"), std::ios_base::in).get();

http_client client (U("my server addy"));

http_response response = client.request(methods::POST, U("path"), stream, U("string")).get();
if(response.status_code() == status_codes::OK)
{
cout<<"Connection to Server Sucessful"<<endl;
    const utility::string_t body = response.extract_string().get();
    std::wcout<<body;
}
else
{
    cout<<"Connection to Server UNSUCCESSFUL"<<endl;
}   
//getchar();
return 0;
}

Thanks again.

Steven
Coordinator
Jan 28, 2015 at 1:01 AM
Hi Steven,

If you debug your application what do you see? Where is the error occurring? Also it seems weird you are setting your Content-Type header to be 'string'.

Steve
Jan 28, 2015 at 3:39 PM
Hi Steven,

It is a weird error because it is not from my code but rather from an exception type. The message reads " Unhandled exception at at 0x7641C41F in XMPUploaded.exe: Microsoft C ++ exception: web::http::http_exception at memory location 0x0055F420. And the excptptr.cpp is open with a break point at RaiseException section. When I close this error box and run exe part of the program, it works and then the program again it works. Please advice on what I can do to make it run one time with no issues.

Also what Content-Type header is advisable for xml content with letters, numbers and signs?

Thanks,

Steven
Coordinator
Jan 28, 2015 at 5:38 PM
Hi Steven,

That is the exact problem then, you are getting an exception which you are not handing so the process is going to crash. You need to catch the http_exception and take a look at the message and error code to see what the problem is. In general you should be aware you need to handle exceptions when using the C++ REST SDK, all network errors are treated as exceptions and thrown as http_exceptions. I also recommend you read up on how to use PPL tasks, the unit of asynchrony in the library.

Steve
Jan 28, 2015 at 6:33 PM
Thank you Steve....I will proceed in the direction you have advised.

-Steven