C# Winform: Call External REST API With POST Method - c#

Hi I am Calling External Rest API, I have Get Correct Results of GET and One POST API Result But this gives the error: The remote server returned an error: (400) Bad Request . But in POSTMAN it is working fine.
In Postman I am Calling http://192.168.x.x:8088/ari/channels/100001.100/play?media=sound:hello-world&api_key=admin:admin&app=myapp1 .
My Code is below and I passing Parameters and query string in API.
I think my problem is in media = sound:hello-world but I have no idea to solve.
string url = String.Format("http://192.168.x.x:8088/ari/channels/play?api_key=admin:admin");
WebRequest requestPost = WebRequest.Create(url);
requestPost.Method = "POST";
requestPost.ContentType = "application/json";
string postData = "{\"channelId\":\"100001.100\",\"media=sound\":\"hello-world\",\"app\":\"myapp1\"}";
using (var streamWriter = new StreamWriter(requestPost.GetRequestStream()))
{
streamWriter.Write(postData);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = requestPost.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var res = streamReader.ReadToEnd();
}

Related

Connecting to Tagpacker.com from C# with a HttpWebRequest

Does anyone know how I can post to the tagpacker website (with the following API in .Net? Because somehow I don't understand the authorization towards their server...
The code I'm currently using is the following:
private readonly HttpWebRequest _httpWebRequest = (HttpWebRequest)
WebRequest.Create("https://tagpacker.com/api/users/{YourUserID}/tags");
public void Load()
{
_httpWebRequest.ContentType = "application/json";
_httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(_httpWebRequest.GetRequestStream()))
{
var json = "{\"user\":\"test\"," +
"\"password\":\"bla\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)_httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
But I'm getting back the following message:
{
"status": 401,
"message": "User not authorized",
"code": "USER_NOT_AUTHORIZED",
"url": "/unauthorizedHandler"
}
The only thing else you get from them is an "API-Access" code like the following: 1b3f314dd132b0015b5415b1:bd0ffe4b-a01e-4bf5-b1ed-12b24145d12d where the first part is your user id and the second is your API-code I guess? Does anyone have an idea on how to use this? Tagpacker's Api FAQs are here.
Official answer from the tagpacker team is that you need to set the api key in the header like the following (Java example):
URL url = new URL("https://tagpacker.com/api/users/<your_user_id>/links?limit=20");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("api_key", "<your_api_key>");
I will try to do this in C# and edit the answer again afterwards.

How to Response HTTP 504: Timer Time Out JSON

I'm using https://timercheck.io/YOURTIMERNAME/60 to create timer, and when the timer end the API Manager to return both an error code and some JSON content
This is the JSON data when timer end:
{"errorMessage":"504: timer timed out"}
When the timer still countdown:
{"timer":"neo308CCEACbid","request_id":"e54f484e-1e64-11e6-9552-3950b2ec2d5c","status":"ok","now":1463732937,"start_time":1463732935,"start_seconds":180,"seconds_elapsed":2,"seconds_remaining":178,"message":"Timer still running"}
Because of the error code, i get error on Visual Studio and App force close on my Android. I only want to get the errorMessage in JSON. I'm using Visual Studio 2015 and Xamarin to make this project.
Thanks in advance
UPDATE:
I'm using this to get web response
private async Task<string> FetchUserAsync(string url)
{
// Create an HTTP web request using the URL:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
// Send the request to the server and wait for the response:
using (WebResponse response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var sr = new StreamReader(response.GetResponseStream()))
{
string strContent = sr.ReadToEnd();
return strContent;
}
}
}
And call it like this:
CekTimer dataWaktu = JsonConvert.DeserializeObject<CekTimer>(await FetchUserAsync(url));
I assume you are using HttpClient and GetStringAsync, and that the HttpResponse Status code is a 504 too, like in the Json Content.
The shortcut methods like GetStringAsync all make a call to EnsureSuccessStatusCode, which of cause throws an exception on a 504 (see source here).
You can just make a direct get Request:
var client = new HttpClient();
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, yourUri));
var json = await response.Content.ReadAsStringAsync();
I found the answer of my problem, because of webservice return error code, just simply use WebException and get the StatusCode like this :
private async Task<string> FetchUserAsync(string url)
{
try
{
// Create an HTTP web request using the URL:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
// Send the request to the server and wait for the response:
using (WebResponse response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var sr = new StreamReader(response.GetResponseStream()))
{
string strContent = sr.ReadToEnd();
return strContent;
}
}
}
catch (WebException e)
{
string a = ((HttpWebResponse)e.Response).StatusCode.ToString();
//Toast.MakeText(this, a, ToastLength.Long).Show();
if (a == "GatewayTimeout")
{
return "{'errorMessage':'504: timer timed out'}";
}
else
{
internetDropDialog();
return "";
}
}
}
I think it isn't the best answer, but it can help you to move on from this problem

OneLogin Create Session Login Token API returns status 400 with message: Bad Request

I am developing a C# application which needs to use the onelogin API to retrieve a session token. I am able to authenticate and and create a token with the following code:
WebRequest Authrequest = WebRequest.Create("https://api.us.onelogin.com/auth/oauth2/token");
Authrequest.Method = "POST";
Authrequest.ContentType = "application/json";
Authrequest.Headers.Add("cache-control", "no-cache");
Authrequest.Headers.Add("Authorization: client_id:XXXXXXX7bbf2c50200d8175206f664dc28ffd3ec66eef0bfedb68c3366420dc, client_secret:XXXXXXXXXX6ba2802187feb23f6450c6812b8e6639361d24aa83f12010f ");
using (var streamWriter = new StreamWriter(Authrequest.GetRequestStream()))
{
string Authjson = new JavaScriptSerializer().Serialize(new
{
grant_type = "client_credentials"
});
streamWriter.Write(Authjson);
}
WebResponse AuthReponse;
AuthReponse = Authrequest.GetResponse();
Stream receiveStream = AuthReponse.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream);
JObject incdata = JObject.Parse(readStream.ReadToEnd());
string sToken = incdata["data"][0]["access_token"].Value<string>();
AuthReponse.Close();
However, when running the Create Session Login Token with the following code, it only returns a 400 error, and the message has no detail. Just Bad Request:
//Get the session token for the specified user, using the token recieved from previous web request
WebRequest request = WebRequest.Create("https://api.us.onelogin.com/api/1/login/auth");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("authorization", "bearer:" + sToken);
using (var streamWriter2 = new StreamWriter(request.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(new
{
username_or_email = sUsername,
password = sPassword,
subdomain = "comp-alt-dev"
});
streamWriter2.Write(json);
}
WebResponse response;
response = request.GetResponse();
string streamText = "";
var responseStream = response.GetResponseStream();
using (responseStream)
{
var streamReader = new StreamReader(responseStream);
using (streamReader)
{
streamText = streamReader.ReadToEnd();
streamReader.Close();
//
}
responseStream.Close();
}
Any ideas?
-Thank you
Also for anyone who may be getting this error. in C# the email is case sensitive. I tried User.email.com. In onelogin it was saved as user#email.com. changing the c# to lower case fixed it.
Can you let us know what payload you're sending across the wire to the .../1/login/auth endpoint as well as the response (either as others have suggested as packet snoop, or just as a debug output from the code)
400 means either bad json or the endpoint requires MFA, so this will narrow it down.
~thanks!
Just joining the troubleshooting effort =) -- I can replicate a 400 Bad Request status code with a "bad request" message when the request body contains a username_or_email and/or subdomain value that does not exist, or if the request body is empty.
Can you post what goes over the wire to the OneLogin endpoint...
OK Thanks. So it appears your subdomain does not exist. If you give me an email in the account I can find the correct subdomain value for you.

Lumens VC LC101 - Authorization error

I'm currently making a web application to control a Lumens LC101. When I login to the device I get a session id, which I use to call commands, for authorization. But when I call a command - for example keepalive - and posted the session with it, Lumens gives me an authorization error code: -14.
This is how I post the session and call a command:
ServicePointManager.Expect100Continue = false;
// Create HttpWebRequest
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://192.168.0.103/api/keepalive");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
// Post json data
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {
streamWriter.Write("{\"session\":\"" + session + "\"}");
streamWriter.Flush();
streamWriter.Close();
}
// Get response of HttpWebRequest
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
// Read stream from response
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
string result = streamReader.ReadToEnd();
JObject jsonResult = JObject.Parse(result);
int code = Int32.Parse(jsonResult.GetValue("code").ToString());
// Return result
if (code >= 0) return result;
int code will be -14 in this case, because authorization failed. But I'm using the same session id, which I got from the login.
How do I make sure it won't give me an authorization error code: -14?
EDIT
This is how it's described in the documentation:
Here's the documentation. Session is described in paragraph 1.2

Can't access Web of Trust (WoT) API w/ JSON.Net

I'm new to JSON & am using VS 2013/C#. Here's the code for the request & response. Pretty straightforward, no?
Request request = new Request();
//request.hosts = ListOfURLs();
request.hosts = "www.cnn.com/www.cisco.com/www.microsoft.com/";
request.callback = "process";
request.key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string output = JsonConvert.SerializeObject(request);
//string test = "hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create("http://api.mywot.com/0.4/public_link_json2?);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = output;
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
MessageBox.Show(e.ToString());
}
//response = true.
//no response = false
return true;
}
When I run this, I get a 405 error indicating method not allowed.
It seems to me that there are at least two possible problems here: (1) The WoT API (www.mywot.com/wiki/API) requires a GET request w/ a body, & httpWebRequest doesn't allow a GET in the httpWebRequest.Method; or (2) the serialized string isn't serialized properly.
NOTE: In the following I've had to remove the leading "http://" since I don't have enough rep to post more than 2 links.
It should look like:
api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx
but instead looks like:
api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}.
If I browse to:api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx; I get the expected response.
If I browse to: api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}; I get a 403 denied error.
If I hardcode the request & send as a GET like below:
var httpWebRequest = (HttpWebRequest) WebRequest.Create("api.mywot.com/0.4/public_link_json2? + "test"); it also works as expected.
I'd appreciate any help w/ this & hope I've made the problem clear. Thx.
Looks to me like the problem is that you are sending JSON in the URL. According to the API doc that you referenced, the API is expecting regular URL encoded parameters (not JSON), and it will return JSON to you in the body of the response:
Requests
The API consists of a number of interfaces, all of which are called using normal HTTP GET requests to api.mywot.com and return a response in XML or JSON format if successful. HTTP status codes are used for returning error information and parameters are passed using standard URL conventions. The request format is as follows:
http://api.mywot.com/version/interface?param1=value1&param2=value2
You should not be serializing your request; you should be deserializing the response. All of your tests above bear this out.

Categories

Resources