C# API POST similar to CURL - c#

I'm trying to use the vultr.com API that utilizes CURL. I have successfully completed a POST call to their API with several different calls, but one in particular will not work. Here is their documentation on the API https://www.vultr.com/api/ .
I am able to get their server/create and firewall/rule_create to work properly with pretty much the same exact code, but it will not work for their server/reboot command. Now here is code for a post to their API that I have successfully gotten to work.
public static void AddIpToFirewall(string ip,string fireWallGroupId)
{
string Data = "FIREWALLGROUPID=" + fireWallGroupId + "&direction=in&ip_type=v4&protocol=tcp&subnet=" + ip + "&subnet_size=32&port=80";
string Reponse = String.Empty;
StreamWriter Sw = null;
StreamReader Sr = null;
try
{
HttpWebRequest Req = (HttpWebRequest)WebRequest.Create("https://api.vultr.com/v1/firewall/rule_create");
Req.Method = "POST";
Req.ContentType = "application/x-www-form-urlencoded";
Req.ContentLength = Data.Length;
Req.Headers.Add(ApiKey);
using (var sw = new StreamWriter(Req.GetRequestStream()))
{
sw.Write(Data);
}
Sr = new
StreamReader(((HttpWebResponse)Req.GetResponse()).GetResponseStream());
Reponse = Sr.ReadToEnd();
Sr.Close();
}
catch (Exception ex)
{
if (Sw != null)
Sw.Close();
if (Sr != null)
Sr.Close();
Console.WriteLine(ex.Message + "\r\n\r\n'error with vultr...");
}
}
Now here is the code that will not work. It's pretty much identical to the firewall POST command.
public static void RebootCommand(string subId)
{
string Data = "SUBID=" + subId;
string Reponse = String.Empty;
StreamWriter Sw = null;
StreamReader Sr = null;
try
{
HttpWebRequest Req = (HttpWebRequest)WebRequest.Create("https://api.vultr.com/v1/server/reboot");
Req.Method = "POST";
Req.ContentType = "application/x-www-form-urlencoded";
Req.ContentLength = Data.Length;
Req.Headers.Add(ApiKey);
using (var sw = new StreamWriter(Req.GetRequestStream()))
{
sw.Write(Data);
}
Sr = new
StreamReader(((HttpWebResponse)Req.GetResponse()).GetResponseStream());
Reponse = Sr.ReadToEnd();
Sr.Close();
}
catch (Exception ex)
{
if (Sw != null)
Sw.Close();
if (Sr != null)
Sr.Close();
Console.WriteLine(ex.Message + " error with vultr...");
}
}
It does not receive an error, but fails to reboot the VM. I've contacted their support and they say that their reboot command is working without any issues. Is there anyone out there that has had this issue before? Thanks.

I figured it out. With all of the other POST requests that I have done from their API the line Req.ContentLength = Data.Length was required. But for whatever reason that line had to be removed to get the reboot command to work.

Related

How can I change the default icon brings OneSignal making a post from Xamarin.Forms?

I have done a post method to consult the OneSignal API Rest, that when an order has been accepted a notification is sent to the user from the device that placed the order and this is the code line that does not work, and it worked without the small_icon, large_icon and android_accent_color
CODE:
public static void PostNotification(string idPush)
{
var request = WebRequest.Create(AppSettings.OneSignalApi) as HttpWebRequest;
request.KeepAlive = true;
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.Headers.Add("authorization", AppSettings.KeyPush);
byte[] byteArray = Encoding.UTF8.GetBytes("{"
+ $"\"app_id\": \"{AppSettings.PushIDApp}\","
+ "\"small_icon\": \"ic_stat_onesignal_default\","
+ "\"large_icon\": \"ic_onesignal_large_icon_default\","
+ "\"android_accent_color\": \"FFba3870\","
+ "\"contents\": {\"en\": \"Pedido Aceptado\"},"
+ $"\"include_player_ids\": [\"{idPush}\"]" +
"}");
string responseContent = null;
try
{
using (var writer = request.GetRequestStream())
{
writer.Write(byteArray, 0, byteArray.Length);
}
using (var response = request.GetResponse() as HttpWebResponse)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
responseContent = reader.ReadToEnd();
}
}
}
catch (WebException ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(new StreamReader(ex.Response.GetResponseStream()).ReadToEnd());
}
}
I have the icons but it does not show them, it does not send me the notification with it, just removing the following 3 properties, small_icon, large_icon and android_accent_color I do not know if the way I am doing it will be wrong, and I have followed the documentation of the Create Notification.

Delay in declaration of StreamWriter variable

In my C# application I have a while loop that gathers a string from a Redis message queue and sends it to a listening server.
At every cicle the connection is opened with an HttpWebRequest Post method and the data is sent using a StreamWriter variable.
Problem is: after sending two strings the application freezes without returning any error, it just does nothing for maybe a minute, after that it works again correctly and continues its job for another couple strings, freeze and so on.
Debug shows the delay happens during the declaration of the StreamWriter variable.
Here is the core of the code:
// configure Redis
var redis = new RedisClient("127.0.0.1");
while (true)
{
// read from Redis queue
string json = redis.BRPop(30, "sensors_data");
//...
//URL DECLARATION
//...
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentLength = json.Length;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Proxy = null;
SendDataAsync(json, url);
}
}
static async Task SendDataAsync(string json, string url)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentLength = json.Length;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Proxy = null;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
try
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
Console.Write("Data Sent");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
catch (Exception err)
{
Console.Write(err.Message);
}
Console.WriteLine();
}
So the code actually works, just there is some strange huge delay where it comes to declare the StreamWriter. Does anyone have any idea? I don't know how to handle the problem.
EDIT
while (true)
{
i = 0;
// read from Redis queue
string json = redis.BRPop(30, "sensors_data");
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentLength = json.Length;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Proxy = null;
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
try
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var response = httpWebRequest.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string reply=reader.ReadToEnd();
Console.WriteLine(reply);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
catch (Exception err)
{
Console.Write(err.Message);
}
Console.WriteLine();
}
Found the solution: Apparently it is necessary to get an answer from the server, after I added the httpWebRequest.GetResponse() and the following two lines I didn't find delays anymore.
Suggestion: it's better to use WebClient, it didn't give me any problem from the first try.

HttpWebRequest.getResponse() returning NULL

I am attempting to create a console app that sends a WebRequest to a website so that I can get some information back from it in JSON format. Once I build up the request and try to get response I just want to simply print out the data, but when I call httpWebRequest.getResponse() it returns NULL.
I have tried multiple other methods of sending the data to the the url but those are all giving me like 404, or 400 errors, etc. This method at least isn't giving me any error, just a NULL.
Here is a snapshot of the documentation I am using for the API (albeit the docs aren't complete yet):
Here is the console app code that I have right now:
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.remot3.it/apv/v27/user/login");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("developerkey", "***KEY***");
using (var streamWriter = new
StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
email = "***EMAIL***",
password = "***PASSWORD***"
});
Console.WriteLine(json);
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
Console.ReadLine();
}
}catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.ReadLine();
}
Expected output is some JSON data, but I am getting a NULL back from getResponse().
Try to serialize the credential in your form and for header send as parameter for this class.
Check below for my code. It is not 100 % fit to your requirement, but atleast it will help to get through your logic.
Here is what I get Json Response from this code. Its work Perfect. Please remember to add timeout option on your webrequest and at the end close the streamreader and stream after completing your task. please check this code.
public static string httpPost(string url, string json)
{
string content = "";
byte[] bs;
if (json != null && json != string.Empty)
{
bs = Encoding.UTF8.GetBytes(json);
}
else
{
bs = Encoding.UTF8.GetBytes(url);
}
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "POST";
if (json != string.Empty)
req.ContentType = "application/json";
else
req.ContentType = "application/x-www-form-urlencoded";
req.KeepAlive = false;
req.Timeout = 30000;
req.ReadWriteTimeout = 30000;
//req.UserAgent = "test.net";
req.Accept = "application/json";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
reqStream.Flush();
reqStream.Close();
}
using (WebResponse wr = req.GetResponse())
{
Stream s = wr.GetResponseStream();
StreamReader reader = new StreamReader(s, Encoding.UTF8);
content = reader.ReadToEnd();
wr.Close();
s.Close();
reader.Close();
}
return content;
}

Why does my API POST Request keep failing?

I am doing an API Post request and cant seem to get it to work. I always get a sendFailure webexception and the response for the exception is always null so catching the exception is useless. It keeps happening when I try to get the httpWebResponse. I noticed too the request.contentlength gave errors at postream getrequeststream so i commented it out. Test.json is the file I use for the request body. I also tested this on different API testers by including the URL, body, and content-type in the header and they worked. I just cant seem to code it for myself. The credentials work I just dont know if im doing the request correctly?
JSON File:
{
"email": "abc#123.com",
"password": "12345",
"facilityNumber": "987654"
}
string filepath = "test.json";
string result = string.Empty;
using (StreamReader r = new StreamReader(filepath))
{
var json = r.ReadToEnd();
var jobj = JObject.Parse(json);
foreach (var item in jobj.Properties())
{
item.Value = item.Value.ToString().Replace("v1", "v2");
}
result = jobj.ToString();
Console.WriteLine(result);
}
try
{
string setupParameters;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.test.com/abcde");
request.AllowAutoRedirect = true;
setupParameters = result;
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
ASCIIEncoding encoding = new ASCIIEncoding();
var postData = setupParameters;
request.Method = "POST";
request.ContentType = "application/json";
byte[] data = encoding.GetBytes(postData);
//request.ContentLength = data.Length;
using (StreamWriter postStream = new StreamWriter(request.GetRequestStream()))//error if uncomment contentlength
{
postStream.Write(postData);
postStream.Flush();
postStream.Close();
}
HttpWebResponse wr = (HttpWebResponse)request.GetResponse();//error occurs
Stream receiveStream = wr.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
}
catch (WebException ex)
{
if (ex.Response != null)
{
using (var errorResponse = (HttpWebResponse)ex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
result = error;
}
}
}
I suggest modifiying your request to follow this format. Especially pay attention to the request.Method and request.ContentType which have caught me out multiple times.
Also, handling the response is easier this way.
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(YOURURL);
request.ContentType = "application/json; charset=utf8";
request.Headers.Add(ADD HEADER HERE IF YOU NEED ONE);
request.Method = WebRequestMethods.Http.Post; // IMPORTANT
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(JSONBODYSTRING));
// I USUALLY YOU JSONCONVERT HERE TO SIMPLY SERIALIZE A STRING CONTAINING THE JSON INFO.
//BUT I GUESS YOUR METHOD WOULD ALSO WORK
streamWriter.Flush();
streamWriter.Close();
}
WebResponse response = request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
// DO WHATEVER YOU'D LIKE HERE
}
} catch (Exception ex)
{
// HANDLE YOUR EXCEPTIONS
}

Make http WebRequest work in C#

I want to get a respond from an http website,I have used this code
// Create a new request to the mentioned URL.
WebRequest myWebRequest = WebRequest.Create("http://127.0.0.1:8080/geoserver/NosazMohaseb/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=NosazMohaseb:GParcelLAyer&maxFeatures=50&outputFormat=application%2Fjson&bbox=5727579.437775434,3838435.3419322656,5727581.1322169611,3838437.0363737918");
// var myWebRequest = WebRequest.Create(myUri);
myWebRequest.Method ="GET";
myWebRequest.Timeout = TimeOut;
if (myWebRequest is HttpWebRequest)
{
( myWebRequest as HttpWebRequest).Accept = "application/json";
(myWebRequest as HttpWebRequest).ContentType = "application/json";
//(myWebRequest as HttpWebRequest).Accept =
(myWebRequest as HttpWebRequest).KeepAlive = false;
(myWebRequest as HttpWebRequest).UserAgent = "SharpMap-WMSLayer";
}
if (Credentials != null)
{
myWebRequest.Credentials = Credentials;
myWebRequest.PreAuthenticate = true;
}
else
myWebRequest.Credentials = CredentialCache.DefaultCredentials;
if (Proxy != null)
myWebRequest.Proxy = Proxy;
try
{
using (var myWebResponse = (HttpWebResponse)myWebRequest.GetResponse())
{
using (var dataStream = myWebResponse.GetResponseStream())
{
var cLength = (int)myWebResponse.ContentLength;
}
myWebResponse.Close();
}
}
catch (WebException webEx)
{
if (!this.ContinueOnError)
throw (new RenderException(
"There was a problem connecting to the WMS server when rendering layer '" + LayerName + "'",
webEx));
}
catch (Exception ex)
{
if (!ContinueOnError)
throw (new RenderException("There was a problem rendering layer '" + LayerName + "'", ex));
}
But when I try to get cLength it is -1,So it does not work,But When I try to access this website
http://127.0.0.1:8080/geoserver/NosazMohaseb/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=NosazMohaseb:GParcelLAyer&maxFeatures=50&outputFormat=application%2Fjson&bbox=5727579.437775434,3838435.3419322656,5727581.1322169611,3838437.0363737918
I get following answer
{"type":"FeatureCollection","totalFeatures":2,"features":[{"type":"Feature","id":"GParcelLAyer.14970","geometry":{"type":"Polygon","coordinates":[[[5727597.96542913,3838442.73401128],[5727595.60003176,3838429.21114233],[5727576.62444883,3838431.10604568],[5727571.16785106,3838432.76483769],[5727569.78420277,3838437.30665986],[5727570.19434939,3838439.63808217],[5727597.96542913,3838442.73401128]]]},"geometry_name":"geom","properties":{"FK_BlockNo":"12055","FK_LandNo":"8","NoApart":"100000","Name":" ","Family":"??","Father":" ","MeliNo":" ","MalekType":"1 ","PostCode":"0 ","Id_Parvande":null,"BuildNo":null,"BuildTypeCode":null,"BuildUserTypeCode":null,"BuildViewTypeCode":null,"BuildGhedmatCode":null,"Farsoode":"0"}}],"crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG::900913"}}}
So it seems I am missing somthing while getting respond using C#..Can you please help me find my mistake?
thanks
In your code you're actually just getting response stream and later you're not reading anything from this stream - that's why you're not getting any data.
You have to create stream reader and use it to read data from response stream (consider to use buffered Read instead of ReadToEnd if your data size is large):
using (var dataStream = myWebResponse.GetResponseStream())
using (var reader = new StreamReader(dataStream))
{
string data = reader.ReadToEnd();
}
Concerning ContentLength equals to -1 in your case - well, it can be something at your server-side, check if your server actually returns this header. In fact, this header is not mandatory and you should not rely on it.

Categories

Resources