I'm trying to send requests and get responses from MailChimp API . . so far, GET, POST and DELETE are working good however, PATCH always results to Bad Request can you identify the error in this code?
string data = "{\"name\": \"TestListTWOTWOTWO\"}";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Headers[HttpRequestHeader.Authorization] = accessToken;
request.Method = "PATCH";
request.ContentType = "text/plain;charset=utf-8";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] bytes = encoding.GetBytes(data);
request.ContentLength = bytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Send the data.
requestStream.Write(bytes, 0, bytes.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
the error occus on the line with request.GetResponse();
it is an unhandled WebException saying The remote server returned an error: (400) Bad Request
after checking the error response, here's the what it says
"Your request doesn't appear to be valid JSON:
\nParse error on line 1:\nPATCH /3.0/lists/9bb\n^\n
Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['"
Many C# libraries seem to try to use the Expect: 100-Continue header, which MailChimp/Akamai has a problem with when combined with PATCH. You have two options.
Turn off Expect: 100-Continue in your HTTP library. In one C# library, you do that with a line of code like Client.DefaultRequestHeaders.ExpectContinue = False
Tunnel the PATCH request through HTTP POST using the X-Http-Method-Override header. Here's more details on that header.
Cause PATCH is a quite new RFC, so you would not expect that more then a few services support it at all. You'd better check that if the service supports it.
You send request using json format, but set content type to "text/plain" is that OK?
Related
I am facing the following issue while issuing request to retrieve the access token. First, I registered the application in developer console and consequently downloaded the client secret file. The content of which is as below: (i have marked secrets as xxxxx).
{"installed":{"client_id":"xxxx","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"xxxx","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
In the developer documentation (located at : https://developers.google.com/identity/protocols/OAuth2InstalledApp ) however, it is given a different address to connect and retrieve the access tokens.
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
I am confused
1. which URI's to use to get access to tokens.
2. What redirect_uri should be used? Is it the local host or the uri as noted in the developer documentation.
When i use the client secret token uri, i receive a 400 bad request and when i use the uri as noted in the developer documentation, I receive forbidden 403.
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
Can someone kindly clarify. It would be an immense help.
I am writing a console application and i do not want to use the C# api already provided. The sample code is located below.
Where am I doing wrong?
string tokenUri = #"https://accounts.google.com/o/oauth2/token";
HttpWebRequest request=(HttpWebRequest) WebRequest.Create(tokenUri);
NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
outgoingQueryString.Add("code", this.clientCode);
outgoingQueryString.Add("client_id", this.clientID);
outgoingQueryString.Add("client_secret", this.clientSecret);
outgoingQueryString.Add("redirect_uri", "https://oauth2-login-demo.appspot.com/code");
outgoingQueryString.Add("grant_type","authorization_code");
string postdata = outgoingQueryString.ToString();
byte[] byteArray = Encoding.UTF8.GetBytes(postdata);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream reqStr = request.GetRequestStream();
reqStr.Write(byteArray, 0, byteArray.Length);
reqStr.Flush();
reqStr.Close();
HttpWebResponse response=request.GetResponse() as HttpWebResponse;
Console.WriteLine(response.StatusCode.ToString());
Found out that url-encoded is not to be used, instead json is expected. revised the code as below and still 400 persist.
string tokenUri = "https://accounts.google.com/o/oauth2/token";
TokenFileds f = new TokenFileds() { client_code = this.clientCode, client_id = this.clientID, client_secret = this.clientSecret, redirect_uri = "urn:ietf:wg:oauth:2.0:oob", grant_type = "authorization_code" };
//string retString=this.SerializeToJson<TokenFileds>(f);
string retString = this.NewjsonLib(f);
byte[] byteArray=Encoding.UTF8.GetBytes(retString);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tokenUri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
request.ContentLength = byteArray.Length;
Stream strm = request.GetRequestStream();
strm.Write(byteArray, 0, byteArray.Length);
strm.Flush();
strm.Close();
HttpWebResponse response =request.GetResponse() as HttpWebResponse;
you need to insure few things before as,
1. While creating the project you have to select other type project.
2. You must enable the drive API's.
3. Then make sure you are posting this url L"/o/oauth2/token" to this server L"accounts.google.com".
4. you are giving Content Type as L"Content-Type: application/x-www-form-urlencoded".
5.and your header should be like this,
wstring wstrHeader = L"code="+ m_wstrAuthCode +
L"&client_id=327293200239-4n4a8ej3jlm1fdufqu7httclg5a28m1a.apps.googleusercontent.com&client_secret=ieEGhWhPhotp0ZegdgRLkOxv&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code";
here you have to replace m_wstrAuthCode to your authentication code.
6.then you will get the Json from server as,
{
"access_token" : "ya29.7gGjEgvIVIMOO7bHegijk2KygAVjjxz7bCOxUvG7OKeKTc66Nom1e9zCqSyzR4V0bTYC",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/Vc9A7nfib4ikeYs0-TBfrs-isvjRDt-JI2ftj0pNVcRIgOrJDtdun6zK6XiATCKT"
}
7.you need to parse it to get the access token.
I'm Getting HTTP 500 error when calling following REST via c#, but I was able to do the POST by using chrome REST Console
Request body sent ( Got from REST console)
Request Url: http://dev-6666.amazonaws.com/CourseEnrollment
Request Method: POST
Status Code: 201
Params: {
"MESSAGE-TYPE": "UserEnrollmentCreate",
"PAYLOAD": "<userstd version=\"\"\"\"><user password=\"\"PSEUDO-5621b55a\"\" lastname=\"\"Wara\"\" emailaddress=\"\"student3#bloody.com\"\" loginid=\"\"BloodyStudent3\"\" firstname=\"\"Buddihi\"\" userid=\"\"19658121\"\" clientid=\"\"117112\"\" createdate=\"\"2014-04-29T03:55:54.873\"\" lastupdate=\"\"2014-05-29T03:55:54.873\"\"><userproperty propertyname=\"\"\"\" propertyvalue=\"\"\"\" createdate=\"\"\"\" lastupdate=\"\"\"\"></userproperty></user></userstd>"
}
C# method used (This is the one getting 500 error)
private void TestCreateUser()
{
string requestData = "{\"MESSAGE-TYPE\":UserEnrollmentCreate,\"PAYLOAD\":\"<userstd version=\"\"\"\"><user password=\"\"PSEUDO-5621b55a\"\" lastname=\"\"Wara\"\" emailaddress=\"\"student3#bloody.com\"\" loginid=\"\"BloodyStudent3\"\" firstname=\"\"Buddihi\"\" userid=\"\"19658121\"\" clientid=\"\"117112\"\" createdate=\"\"2014-04-29T03:55:54.873\"\" lastupdate=\"\"2014-05-29T03:55:54.873\"\"><userproperty propertyname=\"\"\"\" propertyvalue=\"\"\"\" createdate=\"\"\"\" lastupdate=\"\"\"\"></userproperty></user></userstd>}";
byte[] data = Encoding.UTF8.GetBytes(requestData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://dev-6666.amazonaws.com/CourseEnrollment");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
Stream dataStream = request.GetRequestStream();
dataStream.Write(data, 0, data.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
string result = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
form-url-encoded data should be in form (variablename)=(data)&(variablename)=(data)....
The console representation is a bit messy, so the real data string should be
string requestData = "MESSAGE-TYPE=UserEnrollmentCreate&PAYLOAD=<userstd version=\"\"\"\"><user password=\"\"PSEUDO-5621b55a\"\" lastname=\"\"Wara\"\" emailaddress=\"\"student3#bloody.com\"\" loginid=\"\"BloodyStudent3\"\" firstname=\"\"Buddihi\"\" userid=\"\"19658121\"\" clientid=\"\"117112\"\" createdate=\"\"2014-04-29T03:55:54.873\"\" lastupdate=\"\"2014-05-29T03:55:54.873\"\"><userproperty propertyname=\"\"\"\" propertyvalue=\"\"\"\" createdate=\"\"\"\" lastupdate=\"\"\"\"></userproperty></user></userstd>";
The response should have been 400 in a working implementation as you specify application/x-www-form-urlencoded while you post application/json as content.
WebApi probably returns 500 as it tried to decode the content as a form while the content actually is JSON, hence it get's an exception and therefore return 500 as status code.
I have a need to send a POST http request to a server ,but it should not expect a response. What method should i use for it ?
I have been using
WebRequest request2 = WebRequest.Create("http://local.ape-project.org:6969");
request2.Method = "POST";
String sendcmd = "[{\"cmd\":\"SEND\",\"chl\":3,\"params\":{\"msg\":\"Helloworld!\",\"pipe\":\"" + sub1 + "\"},\"sessid\":\"" + sub + "\"}]";
byte[] byteArray2 = Encoding.UTF8.GetBytes(sendcmd);
Stream dataStream2 = request2.GetRequestStream();
dataStream2.Write(byteArray2, 0, byteArray2.Length);
dataStream2.Close();
WebResponse response2 = request2.GetResponse();
to send a request and get back a response. This works fine if the request will get a response back from the server. But, for my need, i just need to send a POST request. And there will be no response associated with the request i am sending. How do i do it ?
If i use the request2.GetRespnse() command , i get an error that "The connection was closed unexpectedly"
Any help will be appreciated. thanks
If you're using the HTTP protocol, there has to be a response.
However, it doesn't need to be a very big response:
HTTP/1.1 200 OK
Date: insert date here
Content-Length: 0
\r\n
refer to this answer.
What you are looking for, I think, is the Fire and Forget pattern.
HTTP requires response as already mentioned by Mike Caron. But as a quick (dirty) fix you could catch the "connnection closed unexpectedly" error and continue.
If your server is OK with this, you can always use RAW socket to send request then close it.
If you don't want to wait for response you can send data in another thread or simple use
WebClient.UploadStringAsync, but note that response always take place after request. Using another thread for request allows you to ignore response processing.
Take a look at this it may help.
public static void SetRequest(string mXml)
{
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://dork.com/service");
webRequest.Method = "POST";
webRequest.Headers["SOURCE"] = "WinApp";
// Decide your encoding here
//webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentType = "text/xml; charset=utf-8";
// You should setContentLength
byte[] content = System.Text.Encoding.UTF8.GetBytes(mXml);
webRequest.ContentLength = content.Length;
var reqStream = await webRequest.GetRequestStreamAsync();
reqStream.Write(content, 0, content.Length);
var res = await httpRequest(webRequest);
}
I'm Trying to access Google Data (Contact, Edit profile data, Calendar ... etc) by using GData and OAuth2.0 server side (Check this link), I finished the first step and got the first code, and when try to post a request to get the oauth2_token I always got the error "The remote server returned an error: (400) Bad Request."
Here is the code I use to POST the request that returns the OAuth2_token:
string clientToken = Request.QueryString["code"];
string post =
string.Format(
#"code={0}&client_id={1}&client_secret={2}&redirect_uri=http://localhost/default.aspx&grant_type=authorization_code",
clientToken, Settings.ClientId, Settings.ClientSecret);
WebRequest httpRequest = WebRequest.Create("https://accounts.google.com/o/oauth2/token");
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
StreamWriter streamWriter = new StreamWriter(httpRequest.GetRequestStream());
streamWriter.Write(post);
streamWriter.Flush();
streamWriter.Close();
var ss = (HttpWebResponse)httpRequest.GetResponse();
Stream stream = ss.GetResponseStream();
Any help??? I spent 2 days till now trying to solve it but in vain :(
could it be that the redirect_uri needs to be URI encoded?
[https://groups.google.com/forum/#!topic/oauth2-dev/9xnn8nUIA2s]
I think you should encode the redirect_uri parameter using HttpUtility.UrlEncode.
also, you should encode the request body using Utf8 encoding:
byte[] encoded = Encoding.UTF8.GetBytes(post);
httpRequest.ContentLength = encoded.Length
hope this helps.
This code is for an outlook plugin. We're trying to POST to a page and are getting this error:
The remote server returned an error: (422) Unprocessable Entity.
The C# code is here:
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
Byte[] postData = asciiEncoding.GetBytes("email=e2#email.com&password=hunter2");
char[] resultHTML = asciiEncoding.GetChars(webClient.UploadData("http://url", "POST", postData));
string convertedResultHTML = new string(resultHTML);
Any idea what could be causing this?
POST data must be encoded prior to be sent out on the wire as ASCII, if you are sending character not in the ASCII range. You should try something like:
Byte[] postData = asciiEncoding.GetBytes(HttpUtility.UrlEncode("email=e2#email.com&password=hunter2"));
Because of its limited functionality, I avoid using WebClient and use WebRequest instead. The code below:
does not expect an HTTP 100 status code to be returned,
creates a CookieContainer to store any cookies we pick up,
sets the Content Length header, and
UrlEncodes each value in the post data.
Give the following a try and see if it works for you.
System.Net.ServicePointManager.Expect100Continue = false;
System.Net.CookieContainer cookies = new System.Net.CookieContainer();
// this first request just ensures we have a session cookie, if one exists
System.Net.WebRequest req = System.Net.WebRequest.Create("http://localhost/test.aspx");
((System.Net.HttpWebRequest)req).CookieContainer = cookies;
req.GetResponse().Close();
// this request submits the data to the server
req = System.Net.WebRequest.Create("http://localhost/test.aspx");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
((System.Net.HttpWebRequest)req).CookieContainer = cookies;
string parms = string.Format("email={0}&password={1}",
System.Web.HttpUtility.UrlEncode("e2#email.com"),
System.Web.HttpUtility.UrlEncode("hunter2"));
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parms);
req.ContentLength = bytes.Length;
// perform the POST
using (System.IO.Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
// read the response
string response;
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return;
using (System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()))
{
response = sr.ReadToEnd().Trim();
}
}
// the variable response holds the results of the request...
Credits: Hanselman, Simon (SO Question)
This is the RoR application telling you that you have not formed a request that it can handle; the destination script exists (otherwise you'd see a 404), the request is being handled (otherwise you'd get a 400 error) and it's been encoded correctly (or you'd get a 415 error) but the actual instruction can't be carried out.
Looking at it, you seem to be loading some email information. The RoR application could be telling you that the username and password is wrong, or that the user doesn't exist, or something else. It's up to the RoR application itself.
I think the code itself is good; it's just that the app at the other end isn't happy about doing what you ask it. Are you missing something else in the request information, like a command? (eg command=getnetemails&email=e2#email.com&password=hunter2) Are you sure the email/password combination you are passing is good?
see here for more on the 422 error.
Add the below line above your code.
System.Net.ServicePointManager.Expect100Continue = false;
Are you trying to access an authentication required page?
it was solved by returning xml instead of just unstructured text on the RoR side