HttpException Request Time out - c#

i can past this url into my browser and get the server time, https://api.binance.je/api/v3/time
But i am unable to get a response using below code. How can i debug this
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// Create a request for the URL.
WebRequest request = WebRequest.Create("https://api.binance.je/api/v3/time");
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Display the status.
Console.WriteLine(response.StatusDescription);
// Get the stream containing content returned by the server.
Stream 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);
// Cleanup the streams and the response.
reader.Close();
dataStream.Close();
response.Close();
}
}
}

I see that you are able to retrieve the json data from the website. Tested this on my side.
However if you are trying to get the value only you need to read the json string (responsefromServer). This can be done by using a nuget pakage called Newtonsoft.
Then you will have to add the following to your code.
Above namespace:
using Newtonsoft.Json.Linq;
In main function before closing reader enz:
//Create jsonObject object from the api call response
JObject jObject = JObject.Parse(responseFromServer);
//Read propertie called serverTime and convert this to string to match variabele set
string time = jObject["serverTime"].ToString();
//Write the given time
Console.WriteLine(time);
Your code will look like the following:
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Net;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
// Create a request for the URL.
WebRequest request = WebRequest.Create("https://api.binance.je/api/v3/time");
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Display the status.
Console.WriteLine(response.StatusDescription);
// Get the stream containing content returned by the server.
Stream 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);
//Create jsonObject object from the api call response
JObject jObject = JObject.Parse(responseFromServer);
//Read propertie called serverTime and convert this to string to match variabele set
string time = jObject["serverTime"].ToString();
//Write the given time
Console.WriteLine(time);
// Cleanup the streams and the response.
reader.Close();
dataStream.Close();
response.Close();
}
}
}

The problem was down to my vpn. Even though i didnt have an active connection. I killed the background service and restarted it and is now working
Similar issue
httpclient-getasync-times-out-when-connected-to-vpn

Related

C# HTTP Post request from a chatbot in MS Bot Framework

I am a very novice C# person so please dont be too hard on me
Im trying to make a post request to MSFLOW from a MSBOT Framwork chatbot. The post request triggers the flow to send an email to chatbot users manager.
I just dont know where to start. I have a basic BOT template from Az but how and where should I put the request
Many thanks
use HttpWebRequest
here is an example of using Http POST request .
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestPostExample
{
public static void Main()
{
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://www.example.com/post");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// 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();
}
}
}
First, the Flow needs an Request - When an HTTP request is received trigger: https://learn.microsoft.com/en-us/azure/connectors/connectors-native-reqres The trigger can be fired by calling it with any rest client: https://flow.microsoft.com/fr-fr/blog/call-flow-restapi/
Most likely, the bot will make the call to the HTTP Request Trigger when the bot is messaged something specific by a user. Notice the BasicBot.cs file has an OnTurnAsync method. Within here, you can check the .Text property of the activity and if it is "send email" then call the Flow Trigger:
if (activity.Type == ActivityTypes.Message)
{
if(active.Text == "send email")
{
await SendEmail();
}
else
{
// other BasicBot.cs code
}
...
As demonstrated by M.zK, you can use WebRequest in C# to make the Flow Trigger call. You can also use HttpClient:
using (var request = new HttpRequestMessage(HttpMethod.Post, "https://prod-13.westus.logic.azure.com:443/workflows/etc"))
{
var content = new { Properties = new { Property1 = "property 1 value", Property2 = "Property 2 value" } };
var json = JsonConvert.SerializeObject(content);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
await client.SendAsync(request).ConfigureAwait(false);
}
}

Passing request headers to HttpWebRequest in C#

I am trying to make a HttpWebRequest and get json data from it. Using Postman, when I set url, parameters & headers, I am able to get json response (please see this). But, using C# when I try, I do not get anything in response.
I searched a couple of posts on Stackoverflow and followed the steps, but cannot find what is wrong or if anything else is required.
string requestUrl = Constants.FLIPKART_INSTALLS_URL;
requestUrl = requestUrl.Replace("##STARTDATE##", DateTime.Now.ToString("yyyy-MM-dd"));
requestUrl = requestUrl.Replace("##ENDDATE##", DateTime.Now.ToString("yyyy-MM-dd"));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
//request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "GET";
//request.ContentType = "application/json";
request.Headers["Fk-Affiliate-id"] = Constants.FLIPKART_AFFILIATE_ID;
request.Headers["Fk-Affiliate-token"] = Constants.FLIPKART_AFFILIATE_TOKEN;
WebResponse response = request.GetResponse();
This is the response that I get. I am not sure if this is really a silly question, but since I don't have much knowledge of C#, therefore I posted it.
Thanks in advance.
By calling GetResponseStream() on the response object, I was able to read the contents, refer below code if needed:
using System;
using System.Net;
using System.Text;
using System.IO;
public class Test
{
// Specify the URL to receive the request.
public static void Main (string[] args)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (args[0]);
// Set some reasonable limits on resources used by this request
request.MaximumAutomaticRedirections = 4;
request.MaximumResponseHeadersLength = 4;
// Set credentials to use for this request.
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
Console.WriteLine ("Content length is {0}", response.ContentLength);
Console.WriteLine ("Content type is {0}", response.ContentType);
// Get the stream associated with the response.
Stream receiveStream = response.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
Console.WriteLine ("Response stream received.");
Console.WriteLine (readStream.ReadToEnd ());
response.Close ();
readStream.Close ();
}
}

Proper Way to open this URL in a C# app

I have a URL that I want to open in my C# app. This URL is used to talk to a communications device, not an internet web site. I have gotten by (I think) all the cert stuff. But the text I get back in the program IS NOT the same thing that CORRECTLY displays when I use a web browser.
Here's the code.
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Web;
namespace VMLConnStatus
{
class Program
{
static void Main(string[] args)
{
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
// Create a request for the URL: https://192.168.30.15/cgi-bin/connstatus?202
String url = "https://192.168.30.15/cgi-bin/";
String data = "connstatus?202";
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create(url);
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = data;
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// 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();
Console.ReadLine();
}
}
public class MyPolicy : ICertificatePolicy
{
public bool CheckValidationResult(ServicePoint srvPoint,
X509Certificate certificate, WebRequest request,
int certificateProblem)
{
//Return True to force the certificate to be accepted.
return true;
}
}
}
The result, though not perfectly displayed in Chrome, should be:
NA NA NA NA 4c:cc:34:02:6d:26 00:23:A7:24:A3:B6
But the text I get in the console window is:
Ok
<HTML>
<HEAD><TITLE>Index of cgi-bin/</TITLE></HEAD>
<BODY BGCOLOR="#99cc99" TEXT="#000000" LINK="#2020ff" VLINK="#4040cc">
<H4>Index of cgi-bin/</H4>
<PRE>
. 15Jun2014 09:48
0
.. 15Jun2014 09:48
0
connstatus 15Jun2014 09:48
19580
firmwarecfg 15Jun2014 09:48
45736
webcm 15Jun2014 09:48
23836
</PRE>
<HR>
<ADDRESS><A HREF="http://www.acme.com/software/mini_httpd/">mini_httpd/1.19 19de
c2003</A></ADDRESS>
</BODY>
</HTML>
Not EVEN close to the same thing.
What am I doing wrong?
Chuck
UPDATE: Code changed. URL, GET, and request writing (presuming I understood the directions). New code is:
static void Main(string[] args)
{
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
// Create a request for the URL: https://192.168.30.15/cgi-bin/connstatus?202
String url = "https://192.168.30.15/cgi-bin/connstatus?202";
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create(url);
// Set the Method property of the request to POST.
request.Method = "GET";
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Get the request stream.
//Now it throws an exception here--------------------------------
//"Cannot send a content-body with this verb-type."
Stream dataStream = request.GetRequestStream();
// 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();
Console.ReadLine();
}
You are using http method POST but the url you have in the comment looks more like GET so then you probably need WebRequest.Create(url + data).
The incorrect response is the index page for https://192.168.30.15/cgi-bin/ which if you put into Chrome will give you the same "wrong" response.
You might not need to write any data to the request stream and can change the Method and ContentType for the request.
The solution required two parts.
First, doing the proper things, thus a total code rework.
I had the dreaded "The server committed a protocol violation. Section=ResponseHeader Detail=Header name is invalid". I tried to make the programatic solution for this work, but it is a .NET 2.0 solution and I was not able to figure it out in .NET4+. So, I edited the .config file and went on.
Here's the final code:
//Initialization
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(#"https://192.168.30.15/cgi-bin/connstatus?202");
//method is GET.
WebReq.Method = "GET";
//Get the response handle
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
//read the response
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
//display it
Console.WriteLine(_Answer.ReadToEnd());
//pause for the ENTER key
Console.ReadLine();
This was added to the .config file in the debug folder (and would be added in the Release folder also..... using VS2013)
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing = "true"/>
</settings>
</system.net>
Thank-you to everyone that replied. The inspiration helped me get to the solution.

POST csv contents to HTTP API C#

Once again, I am new to C# and I am forcing myself through some exercises and putting the theory into practice. I am currently working on a small app to post the contents of a large csv file (2000+ lines) to a http API. The API is in the format
https://mydomain.com//api/dump/?
t = <app_token> // provided by auth function
&[
xml = <device_data_package>
OR
csv = <device_data_package>
My question is, how would i pass the csv contents to the body of the http POST? I appreciate your feedback and help.
Like other answers have said, assuming you have the code to open your file and read the contents, your CSV file will contain a string with values separated by commas. You can add it as a url parameter to give you something like this:
https://mydomain.com//api/dump/?t=my_token&csv=my,values,from,my,csv,file,go,here
However, there are limitations to the length of urls. So if you have anything other than a small CSV file, you are better off sending the CSV data as the body of the post, like you mention in your question.
The method below might come in handy. It takes an object as a parameter and embeds it into a post request and returns the response as a string. I have been using it on a site of mine to send data to an external service. It is part of a much bigger class, so I might have too many using statements.
You would use it like this:
WebUtilities.Post("https://mydomain.com//api/dump/?t=my_token", "csv=" + contents_of_my_csv_file);
The method looks like this:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
using System.Xml;
public static class WebUtilities
{
public static string Post(string url, object postData)
{
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url);
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, postData);
byte[] data = ms.ToArray();
httpWReq.Method = "POST";
httpWReq.ContentType = "application/x-www-form-urlencoded";
httpWReq.ContentLength = data.Length;
using (Stream newStream = httpWReq.GetRequestStream())
{
newStream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
Stream stream = response.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader streamReader = new StreamReader(stream, encode);
string html = streamReader.ReadToEnd();
response.Close();
streamReader.Close();
return html;
}
}
The API should provide some specifications, but usually it'll just be one giant comma separated string like the following:
string foo = "bar1, bar2, bar3, soomanybars, notabar";

Get File Names from Web directory - from Services

Could you please let me know how can i fetch the file names from a web directory at a service level. I have a wrapper services. Inside it I am trying to fetch file names. I couldn't find a solution.
If I understand the question correctly, which I may not since you werent too specific, sounds as easy as getting FTP listing:
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription);
reader.Close();
response.Close();
}
}
}

Categories

Resources