Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you submit a POST Parameter? #28

Closed
danielcaldwell opened this issue Dec 4, 2015 · 7 comments
Closed

How do you submit a POST Parameter? #28

danielcaldwell opened this issue Dec 4, 2015 · 7 comments

Comments

@danielcaldwell
Copy link

I'm creating a JSON array for adding POST parameters to a request.

This is an example of the code I see as the example of how to do this:

web::http::http_request postTestRequest;

postTestRequest.set_request_uri( "/whatever" );
postTestRequest.set_method( web::http::methods::POST );

// create post parameters for the body (as json). 
web::json::value postParameters = web::json::value::array();

postParameters[ L"Parameter1" ] = web::json::value::string( L"Test1" );
postParameters[ L"Parameter2" ] = web::json::value::string( L"Test2" );
postParameters[ L"Parameter3" ] = web::json::value::string( L"Test3" );
postParameters[ L"Parameter4" ] = web::json::value::string( L"Test4" );
postParameters[ L"Parameter5" ] = web::json::value::string( L"Test5" );

postTestRequest.set_body( postParameters );

// create a task
Concurrency::task<web::http::http_response> getTask = m_Client->request( postTestRequest );
... more code below... 

When I run it, I get an access violation exception thrown. Obviously I'm missing something simple here but for the life of me I can't see it. The first exception thrown is here:

https://github.com/Microsoft/cpprestsdk/blob/master/Release/include/cpprest/json.h#L1427

Continuing from that it will break here:
c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\memory :

void operator()(_Ty *_Ptr) const _NOEXCEPT
    {   // delete a pointer
    static_assert(0 < sizeof (_Ty),
        "can't delete an incomplete type");
    delete _Ptr;  // <--- exception thrown here. 
    }
};

I can't continue from that point as it will continually break there.


Also, in the array, I don't see an add(), push_back(), insert(), or any other function that looks like it can add things to these arrays. Any help would be great as I'm stepping through debugging things and the debugger doesn't let me move beyond this point. Even if you continue, it keeps breaking there. I'm using VS 2013.

I don't really care if the body is JSON or whatever, just trying to add some parameters to the post request. However in the requests object I don't see a helper function for adding parameters or anything useful like that.

@kavyako
Copy link
Contributor

kavyako commented Dec 4, 2015

JSON:

I think you want to use a json object instead of an array. While json array is an ordered sequence of values, json object contains key/value pairs.
For example:
json array: [L"Test1", L"Test2", L"Test3"]
json object: {L"Parameter1": L"Test1", L"Parameter2":L"Test2"}
Of course one can nest arrays and objects inside one another.

So here, to create an object you want to do something like:

web::json::value postParameters = web::json::value::object();

postParameters[L"Parameter1"] = web::json::value::string(L"Test1");
postParameters[L"Parameter2"] = web::json::value::string(L"Test2");

For arrays, we provide the index operator:

web::json::value postParameters = web::json::value::array();

postParameters[0] = web::json::value::string(L"Test1");
postParameters[1] = web::json::value::string(L"Test2");

We dont provide the add(), push_back() functions directly on a json value but you could use the array constructor that takes a vector. Similarly use a vector of std::pair<string_t, json::value> for a json object.
std::vectorjson::value e;
e.push_back(web::json::value::string(L"Test1"));
e.push_back(web::json::value::string(L"Test2"));

web::json::value postParameters = web::json::value::array(e);

I recommend using our JSON tests for reference, in this case: construction tests

HTTP_REQUEST
The web::http::http_request::set_body() has overloads that take a vector or string or json_value or streams. You could try using them. Note that the content-type will change based on what you are using. There is an option to specify the content-type to override the defaults.

Let us know if you have any further questions.

@danielcaldwell danielcaldwell changed the title How do you add a parameter to a json array? How do you submit a POST Parameter? Dec 4, 2015
@danielcaldwell
Copy link
Author

Okay, for anyone else who tries to submit a post request there are two things that I found. Your servers may be configured differently.

Problem 1: I tried to use JSON and that won't work. I was only able to get it working using a string which I constructed like this:

wstring testValue = L"Test2";

wstring postParametersWString = 
    L"paramter1=" + L"test1" + L"&" +
    L"paramter2=" + testValue + L"&" +
    L"paramter3=" + L"Test3";

Problem 2: JSON won't work because I had to overwrite the ContentType header to "application/x-www-form-urlencoded" so it was like a form was being submitted. Your server may be configured differently and can parse out the body of a POST request if the content type is plaintext or json.

postRequest.set_body( postParametersWString, L"application/x-www-form-urlencoded" );

RestSharp (http://restsharp.org/) is a good REST library for C#. I created a simple post request there to see how it used it's lower level libraries to submit a request. After stepping through how it handles the post request, I noticed the content type was being changed and that's was the key to getting it to work. Specifically here:

https://github.com/restsharp/RestSharp/blob/master/RestSharp/Http.cs#L356

@kavyako thanks for your feedback. I've changed the name of this issue to reflect the actual question I had. Hopefully it will help others find it if they are struggling to figure out how to use this library to do a simple POST request.

@d34th4ck3r
Copy link

d34th4ck3r commented Apr 14, 2017

I am facing same issue. I am unsure about the best way to make a simple POST request (no JSON) with post parameters. Especially, one with big file as one of the parameters.

I tried creating the postParametersWString as @danielcaldwell mentioned in his answer:

wstring testValue = L"Test2";

wstring postParametersWString = 
    L"paramter1=" + L"test1" + L"&" +
    L"paramter2=" + testValue + L"&" +
    L"paramter3=" + L"Test3";

But this just gives me error C2110: '+': cannot add two pointers

@aawiesinger
Copy link

I am facing a similar issue to this, and getting a response code of 429. This is the code I'm using:

http_client client(L"http://192.168.137.9/api/holographic/os/settings/ipd", config);
http_request req(methods::POST);

// Add base64 result to header
req.headers().add(L"Authorization", L"Basic XYZtaW46Wr6yZW0xMAXY");
req.set_request_uri(L"api/holographic/os/settings/ipd");
req.set_body(L"ipd=5");

return client.request(req);

I'm stuck on what piece I'm missing here.

@aksswami
Copy link

@aawiesinger You can add url query parameters via creating a uri. Here is the sample code.

       auto query_params = {{"ipd" : "5"}, {"key": "value"}};

        auto uri = web::http::uri_builder(endpoint_path);
        for (auto const& param : query_params)
        {
            uri.append_query(param.first, param.second, true);
        }

        web::http::http_request request(method);
        request.set_request_uri(uri.to_uri());

@Bobisback
Copy link

Bobisback commented Apr 27, 2019

What is the correct way to do this?

I am getting errors on all the above approaches. Mainly this error function web::json::value::operator[](const std::string &key) is inaccessible. Any ideas on how to get this to work?

Trying to do this:

        json_v["title"] = web::json::value::string(videoAlert->CameraIp);
	json_v["CreationTime"] = web::json::value::string(timeString);
	json_v["Data"] = web::json::value::string(videoAlert->Data);
	json_v["Message"] = web::json::value::string(videoAlert->Message); 
	json_v["ImagePath"] = web::json::value::string(videoAlert->ImagePath);
	json_v["AlertType"] = web::json::value::number(videoAlert->AlertType);

Number does not error

@sridharb1
Copy link

What is the correct way to do this?

I am getting errors on all the above approaches. Mainly this error function web::json::value::operator[](const std::string &key) is inaccessible. Any ideas on how to get this to work?

All json values are wstrings. So, try json_v[L"title"] = web::json::value::string(wide_string);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants