My code :
string postData = "'Country+Code':'US'&'Start+Date':'2018-01-01'&'End+Date':'2018-07-02'";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
request.Headers["Authorization"] = "Bearer " + accessToken;
var response = (HttpWebResponse)request.GetResponse();
I am getting 404 not found error :
I guess problem in Post data so i tride :
//string postData = "'Country Code':'US'&'Start Date':'2018-01-01'&'End Date':'2018-07-02'";
// string postData = "Country Code:'US':1&Start Date:'2018-01-01'&End Date:'2018-07-02'";
But still got error : 404 not found ,
finding correct way ?
If http status you receiving as 404 (Method Not Found), there are several possibilities for such error :
Ensure service hosted
Url Incorrect
If in case url correct then the ensure the service host as POST method. If its hosted as PUT & if you are calling it as POST then you may receive such error.
If all above case you have verified , cross verify whether you are sending the expected input data as per contract.
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 am trying to make a http post request to obtain an api token. If successful, it is supposed to return string values of access token, token type (bearer) and expires_in.
The code I have is a generic one which I was expecting to see working. But for some reasons, it throws an exception of 400 "The remote server returned an error. Bad Request". I have been trying everything to fix this whereas the result doesn't change.
When I debug the code and see the result in the Output window, there is an exception about Data stream saying "this stream doesn't support seek operations"
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
My doubt is it happens due to the postData, the way it is encoded. My client secret is something like:
g/gOvqf5R+FTZZXbwsCbp0WsQjF9B0bl87IBQ8VAJ2Q=
Does it encode the characters in the secret itself so that it constructs a bad request?
I have also tried this on POSTMAN and it produced a result, so there is nothing with the api. It comes down again to the request content. It's a console app. I am pasting my code below and I am thankful for your help in advance.
public static APIModel GenerateApiKey()
{
var appSettings = ConfigurationManager.AppSettings;
try
{
var urlToCall = string.Format("https://app.example.com/token");
var uri = new Uri(urlToCall);
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
string postData = "grant_type=client_credentials&client_id=" + appSettings["my_client_id"] + "&client_secret=" + appSettings["my_client_secret"];
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var response = (HttpWebResponse)request.GetResponse();
APIModel bearerToken;
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
string jsonFromServer = sr.ReadToEnd();
bearerToken = JsonConvert.DeserializeObject<APIModel>(jsonFromServer);
}
response.Close();
return bearerToken;
}
catch (Exception e)
{
throw new Exception("Error getting a response from API " + e.Message);
}
}
The remote server is giving you a 400 error due to you sending it incorrect data of some sort. You may be able to get the response and figure out the exact error - the remote server would quite possibly give you some more information. However, I can see one issue with your post data - the client secret needs to be URL encoded. Look at the content of it and you will see that it ends with an = sign. that will be interpreted as a special character. I also like to be a bit more explicit about creating strings, so this would work for you:
var postItems = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", "client_credentials"),
new KeyValuePair<string, string>("client_secret", "client_credentials"),
};
string postData = string.Join("&",
postItems.Select (kvp =>
string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value))));
Client id and secret had to be url encoded separately while forming form data. Updated postData:
string postData = "grant_type=client_credentials&client_id=" + HttpUtility.UrlEncode(appSettings["my_client_id"]) + "&client_secret=" + HttpUtility.UrlEncode(appSettings["my_client_secret"]);
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?
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 REST based WCF web-service;
The contract is:
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Xml)]
string EchoWithPost(string message);
The message is:
public string EchoWithPost(string s)
{
return "ECHO with POST : You said " + s;
}
I used the web channel factory to get a response via POST and it works. I used wireshark to tap the message and I can see some important things:
1) That xml is sent
2) The Content Type
From this I have constructed the following request logic:
//5) manually post to the REST service
//Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create(urlOfService + "/rest/EchoWithPOST");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "<EchoWithPost xmlns="http://tempuri.org"><message>Hello</message><EchoWithPost>";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/xml";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
However when I hit the line that says:
dataStream =
response.GetResponseStream();
I get the following error:
"The remote server returned an error : (400) Bad Request"
Could someone help me with what I need to do as I need to be able to tell people how to manually create a POST request to interact with this REST based service.
Any help much appreciated dont really see what else I can try.
I've made a few small changes, so I'll just post the entire thing. Hopefully it works for you. Also, I didn't add any deserializing, figuring you could tackle that as long as you make it past the HTTP 400 error.
A great tool to help you debug these situations is SoapUI. Just setup a "Web TestCase", and you can create your own POST requests and monitor the data that's going back and forth.
-Vito
Interface:
[OperationContract]
[WebInvoke(UriTemplate = "EchoWithPost", Method="POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
string EchoWithPost(string message);
Service:
public string EchoWithPost(string s)
{
return "ECHO with POST : You said " + s;
}
Client:
string urlOfService = "http://somewhere.com/RestService.svc/EchoWithPost";
string postData = "<EchoWithPost xmlns=\"http://tempuri.org/\"><message>Vito</message></EchoWithPost>";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
WebRequest request = WebRequest.Create(urlOfService);
request.Method = "POST";
request.ContentType = "application/xml;";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse webResponse = request.GetResponse();
// Output raw string result
string rawStringResult = new StreamReader(webResponse.GetResponseStream()).ReadToEnd();
HttpContext.Current.Response.Write("\r\n" + rawStringResult);
web.config:
If the content type says that you're sending XML, then you shouldn't escape your XML to send it to the service - at least not the wrapping of the message; if you had some characters which needed escaping in the content (text), then you'd need to escape them. Change postData to the line below, and it should work.
string postData = "<EchoWithPost xmlns=\"http://tempuri.org\"><message>Hello & goodbye</message></EchoWithPost>";
Download this tool http://www.fiddler2.com/fiddler2/
try to call the rest method and see the raw data(request response) in fiddler, you will get the exact info about the error
Well Pete2k, I would say that without running your service it could take some time to reconstruct this. Are you using the WCF 4.0 REST Project? If so it has a help page that should show you what the request data looks like.