UWP POST request like GET - post

I need to send POST request from my UWP app.
I read about it here.
I use one shared HttpClient.
private Windows.Web.Http.HttpClient httpClient;
Initialization:
httpClient = new Windows.Web.Http.HttpClient();
var headers = httpClient.DefaultRequestHeaders;
string header = "Chrome/64.0.3282.140";
if (!headers.UserAgent.TryParseAdd(header))
{
throw new Exception("Invalid header value: " + header);
}
I use this object for all request
But when I use it for POST request, it works like GET request or POST, but without parameters
Uri requestUri = new Uri("http://some_websit.ru");
Dictionary<string, string> pairs = new Dictionary<string, string>();
pairs.Add("par1", "val1");
pairs.Add("par2", "val2");
HttpFormUrlEncodedContent formContent = new HttpFormUrlEncodedContent(pairs)
var result = await httpClient.PostAsync(requestUri, formContent);
string resultContent = await result.Content.ReadAsStringAsync();
It ignore parameters which I give.
I tried to send POST request here http://seriyps.ru/postget/ and it works.

There is nothing wrong with your code, I have tested it locally with the same code, only a different URL, and the POST request is sent properly along with the passed in parameters:
I recommend you to install Telerik Fiddler 4 to see the network traffic and confirm that the parameters are indeed sent. I have used http://example.com just as a sample URL here. I would suspect the problem is rather on the side of the server than your app or that the server expect different parameters than what is being sent.

Related

Why Request in IOS return sucess false( unknown error)?

I make a request to the server asking for login, which takes my mail, password and a firebase token, all of these are sent correctly, however, the response data returns with a false and an unkwown error, this happens only on Ios
Already checked the petition on Insomnia, read various of the jsons returned and reduced the problem to Ios platform, checked the pod file to see if I missed references, but it all seems right
void generatePOSTRequest(string slug, string request, System.Action<string> callback)
{
WWW www;
Dictionary<string,string> postHeader = new Dictionary<string, string>();
postHeader.Add("Method", "POST");
postHeader.Add("Content-Type", "application/json");
byte[] formData = System.Text.Encoding.UTF8.GetBytes(request);
www = new WWW(apiURL + slug, formData,postHeader);
StartCoroutine(WaitForRequest(www,callback));
}
//slug is server/api/login
//request is a json with a mail, a password and the firebase token

Order of object properties is changed while posting data from ionic native http client

I am working on ionic app which will be used on android and iOS platforms. App uses one endpoint to post user data to the backend. Data posted on a backend is as follows:
{
"name": "Citizen Foo",
"emailAddress": "citizen.foo#gmail.com",
"role": "citizen"
}
For security purpose every request which is being sent is validated. In order to do this client sends authorization header with every request. Backend creates one for every request and matches it with one sent by client and then only responds otherwise throw an exception. For creating the authorization header, data sent over post request is also a part of the logic. I have simplified this logic becuase the actual problem is different but this part is important to understand the problem.
Following is the sample code on client side:
var sRequestBody = JSON.stringify(data);
var requestBodyBytes = this.getByteArray(unescape(encodeURIComponent(sRequestBody)));
var authHeader = md5.base64(requestBodyBytes);
var headers = {};
headers['Authorization'] = authHeader;
this.nativeHttp.setDataSerializer('json');
this.nativeHttp.clearCookies();
this.nativeHttp.setSSLCertMode('nocheck');
return Observable.fromPromise(this.nativeHttp.post(url, data, headers));
Then, backend which is asp.net web api, calculates authorization in the same way and matches it with one send by client and gives the response if it matches.
var rawContent = await content.ReadAsByteArrayAsync();
var stringContent = content.ReadAsStringAsync().Result;
var hash = md5.ComputeHash(rawContent);
var authorization = Convert.ToBase64String(hash);
if (authHeader != authorization)
throw;
When the above call is made from android,
value of dataString on client is
"{"name":"Citizen Foo","emailAddress":"citizen.foo#gmail.com","role":"citizen"}"
value of stringContent on server is
"{""name"":""Citizen Foo"",""emailAddress"":""citizen.foo#gmail.com"",""role"":""citizen""}"
and it allows request coming from android app.
When the same is run on iOS and the post user call is made,
Value of dataString on client is
"{"name":"Citizen Foo","emailAddress":"citizen.foo#gmail.com","role":"citizen"}"
Value of stringContent on server is
"{""name"":""Citizen Foo"",""role"":""citizen"",""emailAddress"":""citizen.foo#gmail.com""}"
and it does not allow requst coming from iOS app.
And the only reason it is happening is because of the way user object is serialized/received at the backend when request is made from iOS. Order of properties while sending is name,emailAddress,role. While it is received with order name,role,emailAddress. Thus, the authorization value calculated on server side is different than authHeader coming from client and the call is terminated.
stringContent was added on server side just to debug and understand what is being received at server. Order of the object properties on client is different than object properties received on server side. Is there a way to maintain the order of object properties when the request is made from iOS platform? Direction in any way to solve this problem is appreciated.
One solution that worked for us is this:
this.httpClient.setDataSerializer('utf8');
response = await this.httpClient.post(url, JSON.stringify(postBody), {'Content-Type': 'application/json'});
So key points here are:
utf8 as data serializer
body has to be stringified
header 'Content-Type': 'application/json' has to be set

Simple POST from website to external web api fails

I have an asp .net MVC-page
Im trying to connect to Eventbrite:s api
Simply put, it requires you to send client id to one url, using HttpGET and HttpPOST the result and some more info to another url.
The GET goes fine and I get the required (auth)"code". When I try to make the POST to the second url I get
"Socket Exception: An existing connection was forcibly closed by the
remote host"
I can POST to the second url, using Postman and the info from the GET-request it works ok, I get the auth token just fine.
This is the code Im using
var parameters = new Dictionary<string,string>();
parameters.Add("code", pCode);
parameters.Add("client_secret", CLIENT_SECRET);
parameters.Add("client_id", CLIENT_APP_KEY);
parameters.Add("grant_type", "authorization_code");
using (var client = new HttpClient())
{
var req = new HttpRequestMessage(HttpMethod.Post, pUrl) { Content = new FormUrlEncodedContent(parameters) };
var response = client.SendAsync(req).Result;
return response.Content.ReadAsStringAsync().Result;
}
I have a vague memory of a similar problem when publishing to Azure. Since I have to register my app with a public return url I cant look at the request with fiddler.
My site is running https.
I have also tested adding the below line (from some googling)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
But then I get 404-error...
I have also tested this (with same result)
using (var client = new HttpClient())
{
var response = client.PostAsync(pUrl, content).Result;
authToken = response.Content.ReadAsStringAsync().Result;
}
Ive tested getting the auth code and and running the POST from local machine, same result...
I have contacted eventbrite developer support to see if they can help me as well...
This POST must contain the following urlencoded data, along with a Content-type: application/x-www-form-urlencoded header.
Since your content-type is application/x-www-form-urlencoded you'll need to encode the POST body, especially if it contains characters like & which have special meaning in a form.
Then use the following function to post your data:
using (var httpClient = new HttpClient())
{
using (var content = new FormUrlEncodedContent(parameters))
{
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.PostAsync(url, content);
return await response.Content.ReadAsAsync<TResult>();
}
}
The error message you provided means the remote side closed the connection, the causes are:
·You are sending malformed data to the application.
·The network link between the client and server is going down for some reason.
·You have triggered a bug in the third-party application that caused it to crash.
·The third-party application has exhausted system resources.
·Set ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
For more details, you could refer to this case.
Changed OAuth access token URL from
https://www.eventbrite.com/oauth/token/
to (as specified)
https://www.eventbrite.com/oauth/token
(ie without trailing slash). Now it works

Xamarin Forms ios http request header is always null

I am working on a mobile app using xamarin forms, the application needs to get some data from an api so i use http client to implement that.
so, the http requests work fine on both Android and Windows Phone, but when i try to debug the request on IOS i get an error which of course doesn't show an exception details.. but while debugging i found that the error happens while encoding the contents of the request, so it returns NULL in the IOS case, while it returns the encoded content in both android and windows phone case.
I used different ways to send the resquest and to encode the request, but got the same result.
Here are my trials:
the http request code1:
var values = new Dictionary<string, string>
{
{ "ExpiryDate", dateAndTime.ToString() },
{ "IsHijri", "false" },
{ "CR_No", CetNum.Text }
};
var content = new FormUrlEncodedContent(values);
var response = await client2.PostAsync("https://XXXXXXX.com/api/XXXXXX", content);
and this is the request code trial 2 :
var myContent = JsonConvert.SerializeObject(cert);
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var Response = await client.PostAsync("api/PlaPla/PlaPla",
byteContent).ConfigureAwait(false);
string res = await Response.Content.ReadAsStringAsync();
Those trials work fine and get the content encoded with other platforms, but not IOS.
the error message i get is System.NullReferenceException: Object
reference not set to an instance of an objec
So, is there a different way i should be using to send an http request in the ios scenario ? any help ? Thanks.

OAuth1 Authentication in RestSharp for Twitter API GET and POST methods

Using Postman I'm successfully able to query and create tailored audiences using the Twitter API, using Postman's OAuth 1.0 Authorization. However when trying to do the same with RestSharp I get an Unauthorized error.
"UNAUTHORIZED_ACCESS" - "This request is not properly authenticated".
My GET request authenticates fine, but the POST request fails.
_twitterRestClient = new RestClient("https://ads-api.twitter.com/1")
{
Authenticator = OAuth1Authenticator.ForProtectedResource(ConsumerKey, ConsumerSecret, AccessToken, AccessSecret)
};
var restRequest1 = new RestRequest(string.Format("/accounts/{0}/tailored_audiences", TwitterAccountId), Method.GET);
//this works and gives me a list of my tailored audiences
var response1 = _twitterRestClient.Execute(restRequest1);
var restRequest2 = new RestRequest(string.Format("/accounts/{0}/tailored_audiences?name=SampleAudience2&list_type=EMAIL", TwitterAccountId), Method.POST);
// this results in an "Unauthorized" status code , and the message {\"code\":\"UNAUTHORIZED_ACCESS\",\"message\":\"This request is not properly authenticated\"}
var response2 = _twitterRestClient.Execute(restRequest2);
Turns out this is due to a quirk in RestSharp OAuth1 implementation. I think its related to this issue - https://www.bountysource.com/issues/30416961-oauth1-not-specifing-parameter-type . Part of creating an OAuth1 signature involves gathering all the parameters in the request and other details and then hashing it all. It looks like when the HTTP Method is a POST, then RestSharp is not expecting parameters in the querystring (which makes sense), its expecting them in the post body. Anyhow if you add parameters explicitly then they are picked up and the OAuth1 signing works. (Turns out the twitter API works if these params are in the post body, so I didn't need to explicitly add them to the query string). Updated code that now works:
_twitterRestClient = new RestClient("https://ads-api.twitter.com/1")
{
Authenticator = OAuth1Authenticator.ForProtectedResource(ConsumerKey, ConsumerSecret, AccessToken, AccessSecret)
};
var restRequest1 = new RestRequest(string.Format("/accounts/{0}/tailored_audiences", TwitterAccountId), Method.GET);
var response1 = _twitterRestClient.Execute(restRequest1);
var restRequest2 = new RestRequest(string.Format("/accounts/{0}/tailored_audiences", TwitterAccountId), Method.POST);
restRequest2.AddParameter("name", "SampleAudience2");
restRequest2.AddParameter("list_type", "EMAIL");
var response2 = _twitterRestClient.Execute(restRequest2);

Resources