I am trying to checkin to Foursquare using the API, I have obtained the oauth_token and am doing a POST request with the oauth_token. According to the documentation the endpoint I'm hitting is https://api.foursquare.com/v2/checkins/add. This however returns a 400 Bad Request message. This is my code in C#
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.foursquare.com/v2/checkins/add?oauth_token"+ oauth_token + "&venueId=" + venueId);
request.Method = "POST";
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
When I do the same in curl however, it posts a checkin and I get a json response back
curl --data "oauth_token=[oaut_token]&venueId=[venueId]" https://api.foursquare.com/v2/checkins/add
Ultimately what worked is the following:
using (WebClient wc = new WebClient())
{
System.Collections.Specialized.NameValueCollection reqparm = new System.Collections.Specialized.NameValueCollection();
reqparm.Add("oauth_token", oauth_token);
reqparm.Add("venueId", venueId);
byte[] responsebytes = wc.UploadValues(URI, "POST", reqparm);
string responsebody = Encoding.UTF8.GetString(responsebytes);
}
Thanks everyone for your help!
You should write your data to request input stream: HttpWebRequest.GetRequestStream()
Related
I want to do a web request in a asp.net core project. I tried the following but it doesn't seem to send the data in the request:
using System.Net;
...
//encoder
UTF8Encoding enc = new UTF8Encoding();
//data
string data = "[\"some.data\"]";
//Create request
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
request.Credentials = new NetworkCredential(user, secret);
//Set data in request
Stream dataStream = await request.GetRequestStreamAsync();
dataStream.Write(enc.GetBytes(data), 0, data.Length);
//Get the response
WebResponse wr = await request.GetResponseAsync();
Stream receiveStream = wr.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
I don't get an error, the request was send but it doesn't seem to send the data with the request.
I also can't give the length of the data with the request. Is this a core issue? (ps: The credentials are send correctly)
Can anyone help me?
You may be facing a synchronization context problem.
Try to await the asynchronous methods like GetRequestStreamAsync() and GetResponseAsync() instead of getting the Result property.
//Set data in request
Stream dataStream = await request.GetRequestStreamAsync();
//Get the response
WebResponse wr = await request.GetResponseAsync();
Finally solved it. There was a bug in my external API code where I resolved the API request. The code in my question works (If someone wants to use it).
PS: I edit the code with the remark of ycrumeyrolle
Post(Google+) not working.
I tried to implement post using Google+ Domains API v1 (https://developers.google.com/+/domains/getting-started )
Sending the request works, but GetResponse(), I get error like:
The remote server returned an error: (400) Bad Request.
I am trying using the below sample C# code that I got from Google+ API plus.me
var url = "https://www.googleapis.com/plusDomains/v1/people/me/activities?";
var googleParameters = AppendKeyvalue("access_token", access_token) + AppendKeyvalue("message", message);
var fullurl = url + googleParameters;
HttpWebRequest request= (HttpWebRequest)HttpWebRequest.Create(fullurl);
request.ContentType = " application/x-www-form-urlencoded ";
request.Method = "POST";
UTF32Encoding utfenc = new UTF32Encoding();
byte[] byteArray = utfenc.GetBytes(fullurl);
Stream postStream = request.GetRequestStream();
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
WebResponse response = request.GetResponse();
public static string AppendKeyvalue(string key, string value)
{
return string.Format("{0}={1}&", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value));
}
For creating new post and comment I am referring this url https://developers.google.com/+/domains/posts/creating.
I tried to figure out a fix for it however the solution has not worked so far.
I'm trying to do a WebRequest to a site from a Windows Phone Application.
But is vry important for me to also get the response from the server.
Here is my code:
Uri requestUri = new Uri(string.Format("http://localhost:8099/hello/{0}", metodo));
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUri);
httpWebRequest.ContentType = "application/xml; charset=utf-8";
httpWebRequest.Method = "POST";
using (var stream = await Task.Factory.FromAsync<Stream>(httpWebRequest.BeginGetRequestStream,
httpWebRequest.EndGetRequestStream, null))
{
string xml = "<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Ahri</string>";
byte[] xmlAsBytes = Encoding.UTF8.GetBytes(xml);
await stream.WriteAsync(xmlAsBytes, 0, xmlAsBytes.Length);
}
Unfortunatelly, I have no idea of how I could get the response from the server.
Does anyone have an idea?
Thanks in advance.
Thanks to #max I found the solution and wanted to share it above.
Here is how my code looks like:
string xml = "<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Claor</string>";
Uri requestUri = new Uri(string.Format("http://localhost:8099/hello/{0}", metodo));
string responseFromServer = "no response";
HttpWebRequest httpWebRequest = HttpWebRequest.Create(requestUri) as HttpWebRequest;
httpWebRequest.ContentType = "application/xml; charset=utf-8";
httpWebRequest.Method = "POST";
using (Stream requestStream = await httpWebRequest.GetRequestStreamAsync())
{
byte[] xmlAsBytes = Encoding.UTF8.GetBytes(xml);
await requestStream.WriteAsync(xmlAsBytes, 0, xmlAsBytes.Length);
}
WebResponse webResponse = await httpWebRequest.GetResponseAsync();
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
responseFromServer = reader.ReadToEnd();
}
I hope it will help someone in the future.
This is very common question for people new in windows phone app
development. There are several sites which gives tutorials for the
same but I would want to give small answer here.
In windows phone 8 xaml/runtime you can do it by using HttpWebRequest or a WebClient.
Basically WebClient is a wraper around HttpWebRequest.
If you have a small request to make then user HttpWebRequest. It goes like this
HttpWebRequest request = HttpWebRequest.Create(requestURI) as HttpWebRequest;
WebResponse response = await request.GetResponseAsync();
using (var reader = new StreamReader(response.GetResponseStream()))
{
string responseContent = reader.ReadToEnd();
// Do anything with you content. Convert it to xml, json or anything.
}
Although this is a get request and i see that you want to do a post request, you have to modify a few steps to achieve that.
Visit this place for post request.
If you want windows phone tutorials, you can go here. He writes awesome tuts.
I followed this procedure.
https://techlib.barracuda.com/CudaSign/RestEndpointsAPI
This is my C# code to get an access token.
string userData = "username=email#domain.com&password=mypassword&grant_type=password";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://signnow.mydomain.com/api/index.php/oauth2/token");
request.Accept = "application/json";
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("Authorization", "Basic " + userData);
var response = request.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
{
//JSON output.
}
The following error I got:
The remote server returned an error: (400) Bad Request.
I know this is because of wrong pattern. Can you please help me in getting an access token from sign now?
Thanks in advance!!!
cURL Request:
string data = "username=email#domain.com&password=mypassword&grant_type=password";
WebRequest myReq = WebRequest.Create(myURL + "oauth2/token");
myReq.Method = "POST";
//myReq.ContentLength = data.Length;
myReq.ContentType = "application/x-www-form-urlencoded";
UTF8Encoding enc = new UTF8Encoding();
//myReq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(enc.GetBytes(data)));
myReq.Headers.Add("Authorization", "Basic " + data);
WebResponse wr = myReq.GetResponse();
As far as I can see, the user data should be sent within the payload and not within the header Authorization. The client credentials (ENCODED_CLIENT_CREDENTIALS) must be something associated to your global account on Barracuda.
I suggest you to test your request using curl since the documentation of the tool use it:
curl -H 'Authorization: Basic ENCODED_CLIENT_CREDENTIALS'
--data 'username=user#test.com&password=test&grant_type=password&scope=user%20documents%20user%2Fdocumentsv2' https://capi-eval.signnow.com/api/oauth2/token
The command parameter --data corresponds to the payload of the request POST.
To fix your problem, you shoud update your code as described below:
string encodedUserCredentials =
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes("user:password")));
string userData = "username=email#domain.com&password=mypassword&grant_type=password";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://signnow.mydomain.com/api/index.php/oauth2/token");
request.Accept = "application/json";
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("Authorization", "Basic " + encodedUserCredentials);
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream());
requestWriter.Write(userData);
requestWriter.Close();
var response = request.GetResponse() as HttpWebResponse;
To know what to put within the variable encodedUserCredentials (i.e. values of user and password), see this doc https://techlib.barracuda.com/CudaSign/RestEndpointsAPI#, section "Security and Access Control".
See these two links for more details:
How to pass POST parameters to ASP.Net web request?
How to send authentication header in ASP.Net for set of web request
Hope it helps you,
Thierry
Ok, this may not be the most elegant solution, but I am new to all this. Also I apologize about it being in vb instead of C#
Public Class iqAPI
Public Shared Function postRequest(ByVal url As String, ByVal toSerialize As String, strHeader As String) As DataTable
Dim wHeader As WebHeaderCollection = New WebHeaderCollection
wHeader.Clear()
wHeader.Add(strHeader)
Dim wReq As WebRequest = WebRequest.Create(url)
Dim postData As String = JsonConvert.SerializeObject(toSerialize)
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
wReq.Headers = wHeader
wReq.Method = "POST"
wReq.ContentType = "application/x-www-form-urlencoded"
wReq.ContentLength = byteArray.Length
Dim dataStream As Stream = wReq.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim wResp As WebResponse = wReq.GetResponse()
MsgBox(CType(wResp, HttpWebResponse).StatusDescription)
dataStream = wResp.GetResponseStream()
Using reader As New StreamReader(dataStream)
Dim respFromServer As String = reader.ReadToEnd()
Dim dtCudaClient As DataTable = JsonConvert.DeserializeObject(Of DataTable)("[" & respFromServer & "]")
MsgBox(dtCudaClient.Rows(0).ToString)
iqSTAMP.gvCudaClients.DataSource = dtCudaClient
reader.Close()
dataStream.Close()
wResp.Close()
Return dtCudaClient
End Using
Return Nothing
End Function
A couple things to note, I overloaded this to use an object instead of the string for the toSerialize. It seems when you create a user, you have to have it in a json format and when you are getting a Token you use the above method passing a string the way you have it. I couldn't figure out the create user without having an object that got Serialized into json.
As far as the Encoded_Client_Credentials, that is supplied by CudSign. I am currently trying to figure out how to POST a file to them without much luck. Hope you have an easier time than me.
var client = new RestClient("https://api-eval.signnow.com/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddHeader("authorization", "Basic BASE64_ENCODED_CLIENT_ID:CLIENT_SECRET");
request.AddParameter("application/x-www-form-urlencoded", "username=EMAIL&password=PASSWORD&grant_type=password", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
It looks like you are hitting the wrong endpoint to me but not 100% sure. I added the code that works for me in getting the correct response, minus some minor info. Let me know if this helps if not I am happy to help get the correct response.
Side note: might need to clear cache if anything could be saved from previous attempts.
Side note: you do not need to specify the scope if you are getting an unrestricted access token.
i am facing a problem where i try to communicate with a Ruby API from a C# application.
I need to POST some JSON data, with the parameter name "data" but the API return me: '!! Unexpected error while processing request: invalid %-encoding'.
I tried with Content-Type set to 'application/json' and 'application/x-www-form-urlencoded; charset=utf-8'.
My POST data look like this 'data=some_json_string'.
I figure i should escape the json string, so if it is my problem, how to do it with .NET without using a 3rd party library?
Code:
byte[] data = System.Text.ASCIIEncoding.UTF8.GetBytes(sdata);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.Absolute));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
request.ContentLength = data.Length;
Stream reqStream = request.GetRequestStream();
// Send the data.
reqStream.Write(data, 0, data.Length);
reqStream.Close();
Thanks in advance!
Presuming the string sdata coming in is already in JSON format you could do:
using (WebClient wc = new WebClient())
{
string uri = "http://www.somewhere.com/somemethod";
string parameters = "data=" + Uri.EscapeDataString(sdata);
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string result = wc.UploadString(uri, parameters);
}
Depending on the consuming service it may need the Content-type set to application/json?