WebRequest vs FileWebRequest - c#

I am going through the example exam questions for Microsoft exam 70-483 "Programming in C#".
There is one question the answer to which I don't understand and couldn't find anything about the topic on the Internet.
The question is:
You are implementing a method named ProcessFile that retrieves data files from web servers and FTP servers. The ProcessFile() method has the following method signature:
Public void ProcessFile(Guid dataField, string dataFileUri)
Each time the ProcessFile() method is called, it must retrieve a unique data file and then save the data file to disk.
You need to complete the implementation of the
ProcessFile() method. Which code segment should you use?
FileWebRequest request = FileWebRequest.Create(dataFileUri) as FileWebRequest;
using (FileWebResponse response = request.GetResponse() as FileWebResponse)
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
using (StreamWriter writer = new StreamWriter(dataFieldId + ".dat"))
{
writer.Write(reader.ReadToEnd());
}
-or-
WebRequest request = WebRequest.Create(dataFileUri);
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
using (StreamWriter writer = new StreamWriter(dataFieldId + ".dat"))
{
writer.Write(reader.ReadToEnd());
}
According to the question-making people, the latter snippet, using "WebRequest" is the correct one. But I cannot figure out why the "FileWebRequest" one isn't.
Keep in mind the questions I am doing have been wrong a lot in the past, so maybe this isn't correct, either?

Some hours ago I also have met this question. Early I have not work with this, but by searching info in Google I concluded followings:
the main words in question is from web servers and FTP servers,
that means that dataFileUri may be like http://mywebserver or ftp://myftpserver
when you try to get file from ftp server, for example:
//from answer
var request1 = WebRequest.Create("ftp://myftpserver");
//from answer
var request2 = FileWebRequest.Create("ftp://myftpserver") as FileWebRequest;
var request3 = WebRequest.Create("ftp://myftpserver") as FtpWebRequest;
request1, request3 will have request value with type SystemNet.FtpWebRequest. request2 will be null.
The similar behavior will be when you try to use http://mywebserver: request2, request3 will be null.
when you use WebRequest the type of the request will be automatically detected by transfer protocol
So you don't need to think about whether file stored on web server/file server/ftp server

Related

Why I can't make a Binance order using c# with the official Binance REST API?

I am new to StackOverflow but I heard that there are awesome and helpful people who can help me out. 😉
My mission:
To find a way to make a trade calling the Binance REST API using c#
Without dlls, using my own code (for speed update)
Now I using the Binance.API package but my bot needs to be a bit faster as its speed is not enough.
Also, it would be a great thing to be able to do that without any external sources like dlls. Isn't it? 😎
What I tried:
Success: I can call the public API without problem with "WebRequest" and which there is no need authentication.
WebRequest webrequest = WebRequest.Create("https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT");
WebResponse Response = webrequest.GetResponse();
StreamReader reader = new StreamReader(Response.GetResponseStream());
MessageBox.Show(reader.ReadToEnd());
Success: I can call the REST API without problem with "WebRequest" and which there is need authentication. BUT only the account information.
string dataQueryString = "recvWindow=15000&timestamp=" + Math.Round(Convert.ToDecimal(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds), 0).ToString();
WebRequest webrequest = WebRequest.Create("https://api.binance.com/api/v3/account?" + dataQueryString + "&signature=" + BitConverter.ToString(new HMACSHA256(Encoding.ASCII.GetBytes(tempAPI_Secret)).ComputeHash(Encoding.ASCII.GetBytes(dataQueryString))).Replace("-", string.Empty).ToLower());
webrequest.Method = "GET";
webrequest.Headers.Add("X-MBX-APIKEY", tempAPI_Key);
WebResponse Response = webrequest.GetResponse();
StreamReader reader = new StreamReader(Response.GetResponseStream());
string response = reader.ReadToEnd();
reader.Close();
Response.Close();
!!! THE PROBLEM !!! I can't call the ORDER REST API with "WebRequest" and which there is need authentication. I tried the code below. (It is called the same way as the account information but with the type of POST and of course with the plus parameters needed)
string dataQueryString = "symbol=BTCUSDT&side=SELL&type=LIMIT&quantity=0.00039&price=38878&newOrderRespType=RESULT&recvWindow=15000&timestamp=" + Math.Round(Convert.ToDecimal(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds), 0).ToString();
WebRequest webrequest = WebRequest.Create("https://api.binance.com/api/v3/account?" + dataQueryString + "&signature=" + BitConverter.ToString(new HMACSHA256(Encoding.ASCII.GetBytes(tempAPI_Secret)).ComputeHash(Encoding.ASCII.GetBytes(dataQueryString))).Replace("-", string.Empty).ToLower());
webrequest.Method = "POST";
webrequest.Headers.Add("X-MBX-APIKEY", tempAPI_Key);
WebResponse Response = webrequest.GetResponse();
StreamReader reader = new StreamReader(Response.GetResponseStream());
string response = reader.ReadToEnd();
reader.Close();
Response.Close();
The returned ERROR code:
'The remote server returned an error: (400) Bad Request.'
I can't understand why this is not working. (I tried to do the order with exactly these parameters from the web client manually and it was successful)
I checked these possible problems:
I have enough funds on my spot account
I trying to sell more than the minimum trade amount is
There is the official Binance REST API documentation: HERE
I tried to google it but I couldn't find the solution even here.
Thanks to read it and if you could help me I would really appreciate it. 🙏
If something is not clear please ask it, I will answer!
I was literarly doing the same thing you are a few days ago, except I was using python. I'm also glad to see I'm not the only one who likes coding from scratch.
My solution was to leave the url as is https://api.binance.com/api/v3/account and instead of attaching my order parameters symbol=BTCUSD&side=BUY&etc... onto the url I had to instead encode and send that data through the data parameter of python's built in function urllib.request.Request(url, data, headers)
I don't know C# that well so I wouldn't know how to translate my python code to C#, but I did find this doc link that provides an example on how to send data using a POST request. You could also take a look at my question and answer as another example.

Download file from secure FTP via REST

I'm trying to get my head around how to download a file from a secure FTP server from my AngularJS application using REST.
Thing is, that for security reasons, I can't just append an iframe or set window.location to ftp://myip:81/myfolder/myfile.pdf, so I have to find a way to trigger the download without this. My initial thought was to create a Generic handler which takes the filename and the folder name as parameters and then serve the file to the user through the context.Response somehow.
What I have so far is this:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(path);
request.UsePassive = false;
request.Credentials = new NetworkCredential(ftpHelper.Username, ftpHelper.Password);
request.Method = WebRequestMethods.File.DownloadFile;
using (var response = (FtpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
// stuck here ...
}
}
request.Abort();
I've got a feeling that this isn't possible, though ;-) Can anyone confirm/disprove? And if it can be done, I'd love a small example/hint on this :-)
Thanks!

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host in C#

I have a code where I am sending the URL request and receiving the response and storing it as a String as
public String GenerateXML(String q)// Here 'q' is the URL
{
// Generating the XML file for reference
// Getting the response in XML format from the URL
Debug.WriteLine("The Http URL after URL encoding :" + q);
try
{
Uri signs1 = new Uri(q);
//Debug.WriteLine("The Requested URL for getting the XML data :" + re);
WebRequest request1 = WebRequest.Create(signs1);
HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
//HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
Stream receiveStream = response1.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
String ab = readStream.ReadToEnd();// The mentioned error is showing up here.
// Debug.WriteLine("The data :"+a);
//XmlDocument content2 = new XmlDocument();
// content2.LoadXml(ab);
// content2.Save("C:/Users/Administrator/Downloads/direct.xml");
return ab;
}
catch (System.Net.WebException ex)
{
Debug.WriteLine("Exception caught :" + ex);
return null;
}
}
Why is the connection closed by the remote host?
What are the possibilities of getting rid of the error or at least ignore the error and continue with other URL requests? I have included try and catch so as to escape any error and continue functioning with out any stop. Scoured the internet for solution but solutions to this particular problem is pretty much specific. Please any help is appreciated.
Thanks in advance.
I had similar problems with the connection being forcibly closed with different hosts. Seems the issue can be resolved by altering various properties of the WebRequest object.
The following findings were outlined in a blog post by briancaos: An existing connection was forcibly closed by the remote host
The steps mentioned in the the above post include:
Set WebRequest.KeepAlive to False.
Set WebRequest.ProtocolVersion to HttpVersion.Version10.
Set WebRequest.ServicePoint.ConnectionLimit to 1
It indeed work for me, but I haven't tested it on multiple hosts as of yet. However, I seriously suggest reading the post as it goes into way more detail.
In case the link get's broken, here's the Archive.org cached version.
The actual exception is probably an IOException - you would need to catch that exception type as well as WebException. The actual problem may be that your URL is out of date and the system is no longer running a web server, or perhaps, the request needs to be authenticated/needs a header as #L.B suggests.
Also, you are potentially leaking all sorts of resources. You should be wrapping your WebResponse and streams in using statements.
using (var response = (HttpWebResponse)request.GetResponse())
using (var receiveStream = response.GetResponseStream())
using (var reader = new StreamReader(receiveStream))
{
var content = reader.ReadToEnd();
// parse your content, etc.
}
Had the same problem today, So I also wrapped the request in a try/catch with WebException, in my case, adding:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Before the webRequest did the trick. Also you should be wrapping your WebResponse and streams in using statements as tvanfosson mentioned.
I hope this helps.

How to read a file from a URI using StreamReader?

I have a file at a URI that I would like to read using StreamReader. Obviously, this causes a problem since File.OpenText does not support URI paths. The file is a txt file with a bunch of html in it. I have multiple web pages that use this same piece of html, so I have put it in a txt file, and am reading it into the page when the page loads (I can get it to work when I put the file on the file system, but need to put it in a document repository online so that a business user can get to it). I am trying to avoid using an iframe. Is there a way to use StreamReader with URI formats? If not, what other options are there using C# to read in the txt file of html? If this is not optimal, can someone suggest a better approach?
Is there a specific requirement to use StreamReader? Unless there is, you can use the WebClient class:
var webClient = new WebClient();
string readHtml = webClient.DownloadString("your_file_path_url");
You could try using the HttpWebRequestClass, or WebClient. Here's the slightly complicated web request example. It's advantage over WebClient is it gives you more control over how the request is made:
HttpWebRequest httpRequest = (HttpWebRequest) WebRequest.Create(lcUrl);
httpRequest.Timeout = 10000; // 10 secs
httpRequest.UserAgent = "Code Sample Web Client";
HttpWebResponse webResponse = (HttpWebResponse) httpRequest.GetResponse();
StreamReader responseStream = new StreamReader(webResponse.GetResponseStream());
string content = responseStream.ReadToEnd();
If you are behind a proxy don't forget to set your credentials:
WebRequest request=WebRequest.Create(url);
request.Timeout=30*60*1000;
request.UseDefaultCredentials=true;
request.Proxy.Credentials=request.Credentials;
WebResponse response=(WebResponse)request.GetResponse();
using (Stream s=response.GetResponseStream())
...

Is there any C# equivalent to the Perl's LWP::UserAgent?

In a project I'm invovled in, there is a requirment that the price of certain
stocks will be queryed from some web interface and be displayed in some way.
I know the "query" part of the requirment can be easily implemented using a Perl module like LWP::UserAgent. But for some reason, C# has been chosen as the language to implement the Display part. I don't want to add any IPC (like socket, or indirectly by database) into this tiny project, so my question is there any C# equivalent to the Perl's LWP::UserAgent?
You can use the System.Net.HttpWebRequest object.
It looks something like this:
// Setup the HTTP request.
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com");
// This is optional, I'm just demoing this because of the comments receaved.
httpWebRequest.UserAgent = "My Web Crawler";
// Send the HTTP request and get the response.
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
if (httpWebResponse.StatusCode == HttpStatusCode.OK)
{
// Get the HTML from the httpWebResponse...
Stream responseStream = httpWebResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string html = reader.ReadToEnd();
}
I'm not sure, but are you simply trying to make an HTTP Request? If so, you can use the HttpWebRequest class. Here's an example http://www.csharp-station.com/HowTo/HttpWebFetch.aspx
If you want to simply fetch data from the web, you could use the WebClient class. It seems to be quite good for quick requests.

Categories

Resources