How to go to start of Stream to avoid two webrequests? - c#

I have a small C# console app working that copies the results of a webrequest to a text file and then runs each command in that text file, saving the results to a separate text file.
Problem is, I have to make two requests to the same server, which I don't like doing. The problem is I can't seem to go to the beginning of the Stream/StreamReader after writing it to the text file, forcing me to make another request.
How do I do this with only one webrequest?
Thanks,
John
static void Main(string[] args)
{
// Set all variables
string epoUrl = "https://de-ser2012ecm:8443/remote/core.help.do";
string commandHelpPath = #"C:\Logs\AllCommandsHelp.txt";
string coreHelpPath = #"C:\Logs\CoreHelp.txt";
string epoUsername = "admin";
string epoPassword = "password";
string responseFromServer;
StringReader strReader;
try
{
// Get stream from webrequest
Stream coreStream = WebHelper.GetWebResponseStream(epoUrl, epoUsername, epoPassword);
StreamReader coreReader = new StreamReader(coreStream);
// Write core help page to text file
using (StreamWriter corefile = new StreamWriter(coreHelpPath, true, Encoding.UTF8))
{
responseFromServer = coreReader.ReadToEnd();
// Display the content.
corefile.Write(responseFromServer);
strReader = new StringReader(responseFromServer);
}
// Get new stream from webrequest
Stream commandStream = WebHelper.GetWebResponseStream(epoUrl, epoUsername, epoPassword);
StreamReader commandReader = new StreamReader(commandStream);
using (StreamWriter outfile = new StreamWriter(commandHelpPath, true, Encoding.UTF8))
{
while (!strReader.Peek().Equals(-1))
{
string streamLine = strReader.ReadLine();
string[] words = streamLine.Split(' ');
// Check if first string contains a period that's not at the end
if ((words[0].Contains(".")) & !(words[0].EndsWith(".")))
{
StreamReader helpReader = WebHelper.GetWebResponse(epoUrl + "?command=" + words[0], epoUsername, epoPassword);
string helpResponseFromServer = helpReader.ReadToEnd();
outfile.Write(helpResponseFromServer);
outfile.WriteLine("==============================");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex.Message);
}
finally
{
// Close streams
//coreReader.Close();
//commandReader.Close();
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
}
And the GetWebResponseStream method:
public static Stream GetWebResponseStream(string url, string username, string password)
{
Stream dataStream = null;
try
{
// Set the credentials.
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(url), "Basic", new System.Net.NetworkCredential(username, password));
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
// Create a request for the URL.
WebRequest request = WebRequest.Create(url);
request.Credentials = credentialCache;
// Get the response.
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
return dataStream;
}
catch (Exception ex)
{
Console.WriteLine("GetWebResponse threw an exception: " + ex.Message);
return dataStream;
}
}

Thanks to Gildor for the suggestion that put me on the right track. I had the response, I just needed to copy that string into a StringReader. This automatically resets the cursor so you can read from the top! I updated the code to show the new fix. Thanks to everyone for the suggestions. John

Related

API Call not successful

Good day Guys,
I am trying to Use an SMS API. Everything looks fine from my end but the SMS is not delivering. If i use the URL directly on Browser, it executes.
Or is anything wrong with how i built the string?
Below is the code.
Please Note tht cbo.Title is a comobox, txtFirstname is a Textbox.
public void NewText()
{
string username = "something#gmail.com";
string password = "Password";
string urlStr;
string message=" Dear " + cbo_Title.Text + " " + txt_FirstName.Text + ", Your New Savings Account Number is " + Account_No + ".Welcome to AGENTKUNLE Global Services. Your Future is Our Priority ";
string sender = "AGENTKUNLE";
string recipient=txt_Phone.Text;
urlStr = "https://portal.nigeriabulksms.com/api/?username="+username+"+password="+password+"+sender="+sender+"+message="+message+"+ mobiles="+recipient;
Uri success = new Uri(urlStr);
}
private string SendSms(string apiUrl)
{
var targetUri = new Uri(apiUrl);
var webRequest = (HttpWebRequest) WebRequest.Create(targetUri);
webRequest.Method = WebRequestMethods.Http.Get;
try
{
string webResponse;
using (var getresponse = (HttpWebResponse) webRequest.GetResponse())
{
var stream = getresponse.GetResponseStream();
if (stream != null)
using (var reader = new StreamReader(stream))
{
webResponse = reader.ReadToEnd();
reader.Close();
}
else
webResponse = null;
getresponse.Close();
}
if (!string.IsNullOrEmpty(webResponse?.Trim()))
return webResponse.Trim();
}
catch (WebException ex)
{
ErrorHelper.Log(ex);
}
catch (Exception ex)
{
ErrorHelper.Log(ex);
}
finally
{
webRequest.Abort();
}
return null;
}
You never make a request.
The Uri object is just a container for the uri (see Microsoft Docs).
Check out the HttpClient class if you want to send a request.

Download Latest File in a SharePoint Folder

My current code downloads a SharePoint file from an absolute URL of the file and writes to local.
I want to change it to use the folder URL instead and downloads file in the folder base on some filter.
Can it be done?
Below is my current code snippet:
string fullFilePath = DownloadSPFile("http://MySharePointSite.com/sites/Collection1/Folder1/File1.docx/");
public static string DownloadSPFile(string urlPath)
{
string serverTempdocPath = "";
try
{
var request = (HttpWebRequest)WebRequest.Create(urlPath);
var credentials = new NetworkCredential("username", "password", "domain");
request.Credentials = credentials;
request.Timeout = 20000;
request.AllowWriteStreamBuffering = false;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
serverTempdocPath = Path.Combine(AppConfig.EmailSaveFilePath + "_DOWNLOADED.eml");
using (FileStream fs = new FileStream(serverTempdocPath, FileMode.Create))
{
byte[] read = new byte[256];
int count = stream.Read(read, 0, read.Length);
while (count > 0)
{
fs.Write(read, 0, count);
count = stream.Read(read, 0, read.Length);
}
}
}
}
}
catch (Exception ex)
{
AppLogger.LogError(ex, "");
throw ex;
}
return serverTempDocPath;
}
If your sharepoint site enables sharepoint rest api, you can get the details very easy.
Get list of files
url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files
method: GET
headers:
Authorization: "Bearer " + accessToken
accept: "application/json;odata=verbose" or "application/atom+xml"
and pass query for that
"?filter=$top=1&$orderby=Created desc"
More information
Has you try to format your urlPath ?
like:
string urlPath = "path/to/folder/";
string fileFilter = "Cat.png";
string finalPath= String.format("{0}{1}", urlPath, fileFilter);
(Or anything like this)
(Hope I understand your question and I was able to help you ^^)

HTTP Request to get HTML code in C#

I want to get the HTML code from http://www.w3schools.com/
Here is my code:
static void Main(string[] args)
{
TcpClient client = new TcpClient("www.w3schools.com", 80);
client.SendTimeout = 3000;
client.ReceiveTimeout = 3000;
StreamWriter writer = new StreamWriter(client.GetStream());
StreamReader reader = new StreamReader(client.GetStream());
writer.WriteLine("GET www.w3schools.com HTTP/1.1");
writer.WriteLine("Host: www.w3schools.com");
writer.WriteLine();
writer.Flush();
string response = reader.ReadToEnd();
Console.WriteLine("Got Response: {0}", response);
Console.ReadLine();
}
But I get the following:
Where I'm wrong?
The second element of the GET line should be the query path, not the domain name. This should work:
writer.WriteLine("GET / HTTP/1.1");
writer.WriteLine("Host: www.w3schools.com");
For this TcpClient to work you need to have a Wporking TcpServer.
The correct uri should be like ("https://www.w3schools.com/html/default.asp") where after .com the file name will b provided.
The below code will work even without TcpServer.
public static void getSavedHtmlCode()
{
string html = string.Empty;
try
{
var request = System.Net.HttpWebRequest.Create(string.Format("{0}", "https://www.w3schools.com/html/default.asp"));
request.Method = "GET";
var response = (HttpWebResponse)request.GetResponse();
//prepare as html
//html = new StreamReader(response.GetResponseStream()).ReadToEnd();
// 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);
//prepare as html
html = readStream.ReadToEnd();
Console.WriteLine("Response stream received.");
Console.WriteLine(html);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}

"The underlying connection was closed: The connection was closed unexpectedly." on certain systems

I have a client application which communicates to a central server through web services (python based web service). I am currently using post method to send data. This fails on certain systems while works on most other.
here is the code
//method with post
private bool sendDataToServicePost1 (string url,string data)
{
try
{
string boundary = Guid.NewGuid().ToString().Replace("-", "");
string newLine = "\r\n";
// create cookie
Cookie sessionCookie = new Cookie();
sessionCookie.HttpOnly = true;
sessionCookie.Domain = App.ServerIP;
sessionCookie.Name = "session_id";
sessionCookie.Value = App.SessionId;
// open HTTP web request
HttpWebRequest _webRequest = (HttpWebRequest)WebRequest.Create(url);
// add cookie to request
_webRequest.CookieContainer = new CookieContainer();
_webRequest.CookieContainer.Add(sessionCookie);
//setup POST params
_webRequest.Method = "POST";
_webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
_webRequest.Timeout = 600000;
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write(string.Format(sendFormat, boundary, newLine, "Data", data));
sw.Write("--{0}--{1}", boundary, newLine);
sw.Flush();
_webRequest.ContentLength = ms.Length;
Stream s = _webRequest.GetRequestStream();
ms.WriteTo(s);
ms.Flush();
ms.Close();
s.Close();
var _webResponse = RadWebRetry.ReTryGetWebResponse(_webRequest);
StreamReader _streamReader = new StreamReader(RadWebRetry.ReTryGetResponseStream(_webResponse));
string jsonFormattedResponse = _streamReader.ReadToEnd();
logger.Debug("The response from the save operation : " + jsonFormattedResponse);
}
catch (Exception excp)
{
logger.Fatal("Execption:{0}", excp.ToString());
return false;
}
}
When converting the post method to get it works fine.
//method with Get
private bool sendDataToServiceGet((string url,string data)
{
try
{
HttpWebResponse _webResponse = null;
string urlfull = url + "?Data=" + data;
HttpWebRequest _webRequest = (HttpWebRequest)WebRequest.Create(urlfull);
Cookie sessionCookie = new Cookie();
sessionCookie.HttpOnly = true;
sessionCookie.Domain = App.ServerIP;
sessionCookie.Name = "session_id";
sessionCookie.Value = App.SessionId;
_webRequest.CookieContainer = new CookieContainer();
_webRequest.CookieContainer.Add(sessionCookie);
_webRequest.Method = "GET";
_webResponse = RadWebRetry.ReTryGetWebResponse(_webRequest);
System.IO.StreamReader _streamReader = new System.IO.StreamReader(RadWebRetry.ReTryGetResponseStream(_webResponse));
string jsonFormattedResponse = _streamReader.ReadToEnd();
logger.Debug("The response from the save operation : " + jsonFormattedResponse);
}
catch (Exception excp)
{
logger.Fatal("Execption:{0}", excp.ToString());
return false;
}
}
According to me this exception should not be system related, but we are observing it in system to system basis.

How to use eucalyptus REST api in c#

Could anyone help me with this example of REST api “describe eucalyptus instances” in c# without using AWS sdk for .net?
I give you my sample code. This code is running in aws successfully, but in eucalyptus they give a “404 not found” error.
protected void Page_Load(object sender, EventArgs e)
{
EucaListInstance("xyx/services/Eucalyptus");
}
private void ListEucaInstance(string inboundQueueUrl)
{
// Create a request for the URL.
string date = System.DateTime.UtcNow.ToString("s");
string stringToSign = string.Format("DescribeInstances" + date);
string signature = CalculateEucaSignature(stringToSign, true);
StringBuilder sb = new StringBuilder();
sb.Append(inboundQueueUrl);
sb.Append("?Action=DescribeInstances");
sb.Append("&Version=2013-10-15");
sb.AppendFormat("&AWSAccessKeyId={0}", m_EucaAccessKeyID);
sb.AppendFormat("&Expires={0}", date);
sb.AppendFormat("&Signature={0}", signature);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString());
HttpWebResponse response = null;
Stream dataStream = null;
StreamReader reader = null;
try
{
request.Credentials = CredentialCache.DefaultCredentials;
response = (HttpWebResponse)request.GetResponse();
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(dataStream);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// Cleanup the streams and the response.
if (reader != null)
reader.Close();
if (dataStream != null)
dataStream.Close();
if (response != null)
response.Close();
}
}
private string CalculateEucaSignature(string data, bool urlEncode)
{
ASCIIEncoding ae = new ASCIIEncoding();
HMACSHA1 signature = new HMACSHA1(ae.GetBytes(m_EucaSecretKey));
string retSignature = Convert.ToBase64String(signature.ComputeHash(ae.GetBytes(data.ToCharArray())));
return urlEncode ? HttpUtility.UrlEncode(retSignature) : retSignature;
}
You would get a 404 error if you are sending the request to the wrong URL. I would verify that you are sending to the correct URL, which would typically be along the lines of:
http://eucalyptus.your.domain.here.example.com:8773/services/Eucalyptus
You can find the URL to use in your deployment by looking in your eucarc file for the EC2_URL value, or by running the "euca-describe-services -T eucalyptus" admin command (in versions up to 4.0, for 4.0 onward you would use "-T compute")

Categories