How to send POST request in Xamarin? - c#

I've built my backend in rails.
My email address is "sample#zmail.com" and it's already registered. The password is "28902890" here
After giving the following command in terminal
curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST https://auth-agdit.herokuapp.com/api/v1/sessions -d "{\"user\":{\"email\":\"sample#zmail\",\"password\":\"28902890\"}}"
I get this response from my backend,
{"success":true,"info":"Logged in :) ","data":{"authentication_token":"iexGFwJ6HwERQZ3wJ4NG"}}
Now I need to get this data from my Android app.
I can get json by using WebClient().downloadString() method for simple json where authentication is not needed and the request method is GET.
Now I need to get the output Json for POST method.
How can I accomplish that?

There are several methods of doing this. You could use the Xamarin component called RestSharp. This will provide you with easy methods of interfacing with your backend.
var request = new RestRequest("resource/{id}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("id", 123); // replaces matching token in request.Resource
// add parameters for all properties on an object
request.AddObject(object);
// execute the request
RestResponse response = client.Execute(request);
If you do want to simply use the WebClient class provided by the BCL you can use the WebClient.UploadString(string, string) method like so:
using (WebClient client = new WebClient())
{
string json = "{\"user\":{\"email\":\"sample#zmail\",\"password\":\"28902890\"}}";
client.UploadString("https://example.com/api/v1/sessions, json);
}
If you need more control over the request (such as setting accept headers, etc.) then you can use HttpRequest, see this question for an example of that.

This is how I did it:
WebClient wc = new WebClient();
string baseSiteString = wc.DownloadString("https://auth-agdit.herokuapp.com");
string csrfToken = Regex.Match(baseSiteString, "<meta name=\"csrf-token\" content=\"(.*?)\" />").Groups[1].Value;
string cookie = wc.ResponseHeaders[HttpResponseHeader.SetCookie];
Console.WriteLine("CSRF Token: {0}", csrfToken);
Console.WriteLine("Cookie: {0}", cookie);
wc.Headers.Add(HttpRequestHeader.Cookie, cookie);
wc.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
wc.Headers.Add(HttpRequestHeader.Accept, "application/json, text/javascript, */*; q=0.01");
wc.Headers.Add("X-CSRF-Token", csrfToken);
wc.Headers.Add("X-Requested-With", "XMLHttpRequest");
string dataString = #"{""user"":{""email"":""email_here"",""password"":""password_here""}}";
// string dataString = #"{""user"":{""email"":"""+uEmail+#""",""password"":"""+uPassword+#"""}}";
byte[] dataBytes = Encoding.UTF8.GetBytes(dataString);
byte[] responseBytes = wc.UploadData(new Uri("https://auth-agdit.herokuapp.com/api/v1/sessions.json"), "POST", dataBytes);
string responseString = Encoding.UTF8.GetString(responseBytes);
Console.WriteLine(responseString);

Try with this code:
Uri address = new Uri("http://example.com/insert.php");
NameValueCollection nameValueCollection = new NameValueCollection();
nameValueCollection["Name"] = "string-input";
var webClient = new WebClient();
webClient.UploadValuesAsync(address, "POST", nameValueCollection);

Related

Leaf.XNet C# Sending Body as Json not working

HttpRequest httpRequest = new HttpRequest();
RequestParams reqParams = new RequestParams { };
httpRequest.IgnoreProtocolErrors = true;
reqParams["data"] = "{\"path\": \"/Prime_Numbers.txt\"}";
httpRequest.AddHeader("Authorization", " Bearer MYKEY");
httpRequest.AddHeader("Content-Type", "application/json");
Console.WriteLine(httpRequest.Post("https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings", reqParams).ToString());
Im getting the following error: Error in call to API function "sharing/create_shared_link_with_settings": request body: could not decode input as JSON. I am using the dropbox api.
I saw the following: https://github.com/csharp-leaf/Leaf.xNet/issues/66 (Someone had a similar issue, but this fix did not work)
When you are using RequestParams that means Context-Type: application/x-www-form-urlencoded.
You can't set Content-Type via .AddHeader(), use argument for .Post(url, json, contentType) method like this:
HttpRequest httpRequest = new HttpRequest();
httpRequest.AddHeader("Authorization", " Bearer MYKEY");
string url = "https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings";
string jsonData = "{\"path\": \"/Prime_Numbers.txt\"}";
string response = httpRequest.Post(url, jsonData, "application/json").ToString();
Console.WriteLine(response);

Converting Curl to C# with RestSharp

I'm trying to convert this curl command to C# using RestSharp, and I'm having problems specifically with the data parameter (token and uri variables have been replaced w/dummy values for this example):
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'UserToken: usertoken' --header 'AppToken: apptoken' -d '[{"individualRecordNumber":"foo","score":"bar"}]' 'apiEndpoint'
I've been able to successfully do several GET requests within this same API, so I'm good with the overall request format and headers, I'm just having issues figuring out how to format the data and where to append it. Here's the rest of the request without the data:
var client = new RestClient(apiEndpoint);
var request = new RestRequest(Method.POST);
request.AddHeader("usertoken", usertoken);
request.AddHeader("apptoken", apptoken);
request.AddHeader("content-type", "application/json");
IRestResponse response = client.Execute(request);
I've tried using both AddParameter and AddJsonBody with various combinations of serialized and unserialized versions of the data.
Example of building data directly as string:
string examInfo = #"[{""individualRecordNumber"":""foo"",""score"":""bar""}]";
Example of building data as object:
object[] arrayObj = new object[1];
arrayObj[0] = new { individualRecordNumber = "foo", score = "bar" };
This is for a project with an extremely tight turnaround, so any help is much appreciated!
If you need a Post, to "wire in" the Post-Body, AddParameter has this overload
request.AddParameter("application/json", "mybody", ParameterType.RequestBody);
or , in your case
request.AddParameter("application/json", examInfo, ParameterType.RequestBody);
but maybe better (if you have later version)
request.AddJsonBody(new { A = "foo", B = "bar" });
And the initial constructor: (which you seem to have, but making sure to note it for future readers)
var request = new RestRequest(Method.POST);
More full example:
var client = new RestClient("https:blahblahblah");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/json");
/* option1 */
request.AddParameter("application/json", "{mybody:'yes'}", ParameterType.RequestBody);
/* OR option 2 */
request.AddJsonBody(new { A = "foo", B = "bar" });
IRestResponse response = client.Execute(request);

How to pass API_KEY through HttpWebRequest

I'm trying to send curl request passing some headers and authentication info.
All information i want to send went successfully but I'm stuck with how to send the api key that should be used instead of the normal username/password manner.
when I use online curl websites to send the curl request, I put : after the api key and then everything works perfectly.
And this is what i want to do in C# using HttpWebRequest
This is the code I'm using in order to do that:
string credentials = String.Format("{0}:{1}", "API_KEY", "GivenApiKey: ");
byte[] bytes = Encoding.ASCII.GetBytes(credentials);
string base64 = Convert.ToBase64String(bytes);
string authorization = String.Concat("Basic ", base64);
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.website.com/test");
httpWebRequest.ReadWriteTimeout = 100000;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Accept = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.UserAgent = "GivenUserAgent";
httpWebRequest.Credentials = new NetworkCredential("Authorization", authorization);
please any help?
You should put the Authorization in a Header so:
httpWebRequest.Headers["Authorization"] = "Bearer " + apikey;
Depending on the server you are contacting, you'll have to determine the input. In my case Bearer should be placed before the apikey.
As most servers use the following setup for authorization:
Authorization: <type> <credentials>

How to set Twitch TV channel title

I am working on being able to have my custom chat bot to update my primary channel's title (status). I am following this post and I am trying to get the access_token from the REDIRECT_URI.
The URI that contains the redirect is:
https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=channel_editor
I have manually tested this with my CLIENT_ID and REDIRECT_URI set to http://localhost and I get this response from the above URI (which is what I want):
http://localhost/#access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&scope=channel_editor
I am trying to get the access_token from this URI, but I cant seem to get to it from the code below. My response is:
https://api.twitch.tv/kraken/oauth2/authenticate?action=authorize&client_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&redirect_uri=http%3A%2F%2Flocalhost&response_type=token&scope=channel_editor
Code:
string clientID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string redirectURL = "http://localhost";
string url = string.Format("https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id={0}&redirect_uri={1}&scope=channel_editor",
clientID, redirectURL);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = false;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string redirUrl = response.Headers["Location"];
response.Close();
// Show the redirected url
Console.WriteLine("You're being redirected to: " + redirUrl);
This is a console application
This is not directly related to c# but implementing it should be easy enough https://discuss.dev.twitch.tv/t/how-to-set-title/390/2
This twitch dev post helped me out until I got to the "Make the request" step. My problem was I needed to make the C# equivalent of this cURL command to change the channel's title:
curl -H 'Accept: application/vnd.twitchtv.v2+json'
-H 'Authorization: OAuth <access_token>'
-d "channel[status]=New+Status!&channel[game]=New+Game!"
-X PUT https://api.twitch.tv/kraken/channels/CHANNEL
Solution:
I decided to manually get the access_token from the authentication request by ctrl + c and ctrl + v the token from the URI given below and store it into my database:
http://localhost/#access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&scope=channel_editor
Then, I used Postman to generate my RestSharp code with the body request in JSON:
string accessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var client = new RestClient("https://api.twitch.tv/kraken/channels/CHANNEL_NAME");
var request = new RestRequest(Method.PUT);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "OAuth " + accessToken);
request.AddHeader("accept", "application/vnd.twitchtv.v3+json");
request.AddParameter("application/json", "{\"channel\":{\"status\":\"Hello World\"}}",
ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Making HTTP Post with authorization in C#

I'm trying to Make your first call Paypal where the post message are in curl. I want to convert them to C#. But I can't edit Accept header.
curl https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-H "Accept-Language: en_US" \
-u "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp" \
-d "grant_type=client_credentials"
My code is
string url = "https://api.sandbox.paypal.com/v1/oauth2/token";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//request.ContentType = "Content-type: text/xml";
//Client.Headers.Add(HttpRequestHeader.UserAgent, "user agent to send");
//request.Headers.Add(HttpRequestHeader.Accept, "application/json");
//request.Headers.Add(HttpRequestHeader.Referer, "string");
//request.Headers.Add(HttpRequestHeader.AcceptLanguage, "string");
request.Method = "POST";
string authInfo = "AfKNLhCngYfGb-Eyv5gn0MnzCDBHD7T9OD7PATaJWQzP3I1xDRV1mMK1i3WO:ECSAgxAiBE00pq-SY9YB5tHw0fd2UlayHGfMr5fjAaULMD2NFP1syLY7GCzt";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
//request.Headers["Accept"] = "application/json";
request.Headers["Accept-Language"] = "en_US";
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("grant_type=client_credentials");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
I'm getting internal server error 500. But it works fine with curl. How can I do this in C#?
One method I have used before to supply named values like this is to use the UploadValues method of a WebClient. This perfectly replicates the functionality you find in curl (I have used this for integration with the Instagram API for the same purpose).
Here is a little sample code to illustrate:
string authInfo = "AfKNLhCngYfGb-Eyv5gn0MnzCDBHD7T9OD7PATaJWQzP3I1xDRV1mMK1i3WO:ECSAgxAiBE00pq-SY9YB5tHw0fd2UlayHGfMr5fjAaULMD2NFP1syLY7GCzt";
WebClient client = new WebClient();
NameValueCollection values;
values = new NameValueCollection();
values.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo)));
values.Add("Accept", "application/json");
values.Add("Accept-Language", "en_US");
client.UploadValues("https://api.sandbox.paypal.com/v1/oauth2/token", values);
This may not work out of the box (as I have laid it out above) but will hopefully take you in the right direction.

Categories