Zip file from URL not valid - c#

I followed another post to be able to zip the content of an URL..
When I click my button Download, I "zip" the content of the URL and I save it in the default download folder...
So far this is my code:
WebClient wc = new WebClient();
ZipFile zipFile = new ZipFile();
string filename = "myfile.zip";
zipFile.Password = item.Password;
Stream s = wc.OpenRead(myUrl);
zipFile.AddeEntry(filename, s);
return File(s, "application/zip", filename);
it´s similar to this one (which zips the content of a folder... ) (It works correctly)
ZipFile zipFile = new ZipFile();
zipFile.Password = item.Password;
zipFile.AddDirectory(sourcePath, "");
MemoryStream stream = new MemoryStream();
zipFile.Save(stream);
zipFile.Dispose();
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/zip", fileName);
So, I want to do exactly the same with an URL..
THanks!

at the end I use this code and It works like I wanted...
Thanks to all again!
string fileName = "filename" + ".zip";
MemoryStream stream = new MemoryStream();
ZipFile zipFile = new ZipFile();
WebRequest webRequest = WebRequest.Create(myUrl);
webRequest.Timeout = 1000;
WebResponse webResponse = webRequest.GetResponse();
using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
{
string content = reader.ReadToEnd();
zipFile.AddEntry("myfile.txt", content);
}
zipFile.Save(stream);
zipFile.Dispose();
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/zip", fileName);

The example you provide will create an entry inside your zip file with the contents from the stream but you are doing nothing to save and return the actual zip file. You need to use the creation code from your second example.
// name of zip file
string filename = "myfile.zip";
// filename of content
string contentName = "mypage.html";
WebClient wc = new WebClient();
ZipFile zipFile = new ZipFile();
zipFile.Password = item.Password;
Stream s = wc.OpenRead(myUrl);
zipFile.AddeEntry(contentName, s);
MemoryStream stream = new MemoryStream();
zipFile.Save(stream);
zipFile.Dispose(); // could use using instead
s.Dispose(); // could use using instead....
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/zip", fileName);
this will return a zip file with one file in it called content.html containing the contents of the url stream

Related

Certain big '.xlsx' extension files failed to open after downloaded via SftpClient

I am trying to download file from a remote linux server to my local computer using SftpClient.
Here is my code to download the file
public MemoryStream DownloadFile2(string path)
{
var connectionInfo = _taskService.GetBioinformaticsServerConnection();
MemoryStream fileStream = new MemoryStream();
using (SftpClient client = new SftpClient(connectionInfo))
{
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(200);
client.Connect();
client.DownloadFile(path, fileStream);
fileStream.Seek(0, SeekOrigin.Begin);
var response = new MemoryStream(fileStream.GetBuffer());
return fileStream;
}
}
And here is the controller that called above method.
public FileResult DownloadFile(string fullPath, string fileName)
{
if (!string.IsNullOrEmpty(fileName))
{
fullPath = string.Concat(fullPath, "/", fileName);
}
var ms = _reportAPI.DownloadFile2(fullPath);
var ext = Path.GetExtension(fullPath);
if (ext == ".xlsx")
{
return File(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}
return File(ms, "application/octet-stream", fileName);
}
I have manage to do it for most of the files, however for certain large '.xlsx' extension files, when I tried to open it, for some reason, I received below error.
If I am on IISExpress, I still manage to open it after I clicked on 'Yes' button, but if I'm using the normal IIS, it failed to open the file after clicked on 'Yes' button.
For other type of files or smaller excel files, it works as expected.
Any idea how can I modified my code to solve this issue?
I was able to resolve this by modifying my code as below
public MemoryStream DownloadFile2(string path)
{
var connectionInfo = _taskService.GetBioinformaticsServerConnection();
MemoryStream fileStream = new MemoryStream();
byte[] fileBytes = null;
using (SftpClient client = new SftpClient(connectionInfo))
{
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(200);
client.Connect();
client.DownloadFile(path, fileStream);
fileBytes = fileStream.ToArray();
var response = new MemoryStream(fileBytes);
return response;
}
}

Trouble downloading a zip file from my server

I've set up a server endpoint that will zip a folder of files and return the zip file. On the client-side, I have code that calls the endpoint and saves the downloaded zip file to disk. All the code runs, but the resultant file is bigger than the zip file on the server and if I try to open the resultant zip file, I get "Windows can't open the file, file is invalid". What am I doing wrong?
Server code:
[Route("projects/files/download")]
[HttpPost]
public ActionResult Post([FromForm] DownloadFileRequest request)
{
string filesPath = ...;
string zipName = ...;
if (!Directory.Exists(filesPath)) {`
return BadRequest("File path not found on server");
}
if (System.IO.File.Exists(zipName)) System.IO.File.Delete(zipName);
System.IO.Compression.ZipFile.CreateFromDirectory(filesPath, zipName);
byte[] fileBytes = System.IO.File.ReadAllBytes(zipName);
FileContentResult zipFile = File(fileBytes, "application/zip", fileName);
return Ok(zipFile);
}
Client code:
Uri uri = new Uri("https://.../projects/files/download");
response = client.PostAsync(uri.ToString(), formContent).Result;
if (response.IsSuccessStatusCode)`
{
using (HttpContent content = response.Content)
{
Stream stream = content.ReadAsStreamAsync().Result;
string path = ...;
stream.Seek(0, SeekOrigin.Begin);
using (Stream streamToWriteTo = File.Open(path, FileMode.Create))
{
stream.CopyTo(streamToWriteTo);
}
}
}
Instead of returning the Ok(zipFile), just return the file:
return File(fileBytes, "application/zip", fileName);

c# files downloaded with httpwebrequest and cookies get corrupted

I am trying to make a program which is able to download files with URI(URL) using httpwebrequest and cookies(for credential information to keep login status).
I can download files with following code but files get corrupted after being downloaded.
when I download xlsx file(on the web page) into text file at local drive, I see some part of numbers and words from an original file in a corrupted file, therefore I assume I have reached to the right file.
however, when I download xlsx file(on the web page) in xlsx file at local drive, it seems like it fails to open saying
excel cannot open the file 'filename.xlsx' because the file format or
file extension is not valid. Verify that the file has not been
corrupted and that the file extension matches the format of the file.
Is there any way I can keep fully original file content after I download?
I attach a part of result content as well.
private void btsDownload_Click(object sender, EventArgs e)
{
try
{
string filepath1 = #"PathAndNameofFile.txt";
string sTmpCookieString = GetGlobalCookies(webBrowser1.Url.AbsoluteUri);
HttpWebRequest fstRequest = (HttpWebRequest)WebRequest.Create(sLinkDwPage);
fstRequest.Method = "GET";
fstRequest.CookieContainer = new System.Net.CookieContainer();
fstRequest.CookieContainer.SetCookies(webBrowser1.Document.Url, sTmpCookieString);
HttpWebResponse fstResponse = (HttpWebResponse)fstRequest.GetResponse();
StreamReader sr = new StreamReader(fstResponse.GetResponseStream());
string sPageData = sr.ReadToEnd();
sr.Close();
string sViewState = ExtractInputHidden(sPageData, "__VIEWSTATE");
string sEventValidation = this.ExtractInputHidden(sPageData, "__EVENTVALIDATION");
string sUrl = ssItemLinkDwPage;
HttpWebRequest hwrRequest = (HttpWebRequest)WebRequest.Create(sUrl);
hwrRequest.Method = "POST";
string sPostData = "__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=" + sViewState + "&__EVENTVALIDATION=" + sEventValidation + "&Name=test" + "&Button1=Button";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] bByteArray = encoding.GetBytes(sPostData);
hwrRequest.ContentType = "application/x-www-form-urlencoded";
Uri convertedURI = new Uri(ssDwPage);
hwrRequest.CookieContainer = new System.Net.CookieContainer();
hwrRequest.CookieContainer.SetCookies(convertedURI, sTmpCookieString);
hwrRequest.ContentLength = bByteArray.Length;
Stream sDataStream = hwrRequest.GetRequestStream();
sDataStream.Write(bByteArray, 0, bByteArray.Length);
sDataStream.Close();
using (WebResponse response = hwrRequest.GetResponse())
{
using (sDataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(sDataStream);
{
string sResponseFromServer = reader.ReadToEnd();
FileStream fs = File.Open(filepath1, FileMode.OpenOrCreate, FileAccess.Write);
Byte[] info = encoding.GetBytes(sResponseFromServer);
fs.Write(info, 0, info.Length);
fs.Close();
reader.Close();
sDataStream.Close();
response.Close();
}
}
}
}
catch
{
MessageBox.Show("Error");
}
}
StreamReader is for dealing with text data. Using it corrupts your binary data(excel file).
Write sDataStream directly to file. For ex.
sDataStream.CopyTo(fs)
PS: I prepared a test case (using similar logic) to show how your code doesn't work
var binaryData = new byte[] { 128,255 };
var sr = new StreamReader(new MemoryStream(binaryData));
var str3 = sr.ReadToEnd();
var newData = new ASCIIEncoding().GetBytes(str3); //<-- 63,63
Just compare binaryData with newData

Decompressing a zipfile into memory stream - C#

I have written code to store the encoded string of zip file into temp path and now I want to store the encoded zipfile string to memorystream instead of temp path. Can someone please help me how to read the stream and pass it as a string to ZipFile class...I am using DOTNETZIP library to unpack password protested file.
Please see below my code.
string tempPath = Path.GetTempPath();
foreach (ActivityMimeAttachment a in attachments.Entities)
{
if (a.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
{
string strcontent = a.Body;
byte[] filecontent = Convert.FromBase64String(strcontent); // unpack the base-64 to a blob
File.WriteAllBytes(tempPath + a.FileName, filecontent); // Working code creates a zip file
string attachmentfile = tempPath + a.FileName;
using (ZipFile zip = new ZipFile(attachmentfile))
{
foreach (ZipEntry entry in zip.Entries)
{
if ((entry.FileName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) ||
(entry.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)))
{
entry.ExtractWithPassword(tempPath, "password");
FileStream inFile;
byte[] binaryData;
string file = tempPath + entry.FileName;
inFile = new FileStream(file, FileMode.Open, FileAccess.Read);
binaryData = new Byte[inFile.Length];
long bytesRead = inFile.Read(binaryData, 0,
(int)inFile.Length);
inFile.Close();
You'll want to convert your file content to a memory stream (Stream filestream = new MemoryStream(filecontent)) then use ZipFile.Read(fileStream). Then use a StreamReader to get the contents out as a string. So try something like this (note it's untested):
string myString;
byte[] filecontent = Convert.FromBase64String(strcontent);
using (var filestream = new MemoryStream(filecontent))
{
using (ZipFile zip = ZipFile.Read(filestream))
{
foreach (ZipEntry entry in zip.Entries)
{
if ((entry.FileName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) ||
(entry.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)))
{
using (var ms = new MemoryStream())
{
entry.ExtractWithPassword(ms, "password");
ms.Position = 0;
var sr = new StreamReader(ms);
myString = sr.ReadToEnd();
}
...
If the results should be a base64 string, do this:
entry.ExtractWithPassword(ms, "password");
ms.Position = 0;
myString = Convert.ToBase64String(ms.ToArray());
You may or may not have to reset the stream position, but it's good practice to.
Now you can use the results as a string without having to write to a file first.

How do i buffer an image from external link

I have a external link with an image which i want to stream, but i get this error when i try.
error
"URI formats are not supported."
I tried to stream:
Stream fileStream = new FileStream("http://www.lokeshdhakar.com/projects/lightbox2/images/image-2.jpg", FileMode.Open);
byte[] fileContent = new byte[fileStream.Length];
can anyone put some light on this.
Thanks
The FileStream contructor you are using must be provided with a path on your local harddrive and not with an external URL.
You are probably looking for this:
string url = "http://www.lokeshdhakar.com/projects/lightbox2/images/image-2.jpg";
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse();
Stream stream = httpWebReponse.GetResponseStream();
Probably also for this:
Image pic = Image.FromStream(stream);
MemoryStream ms = new MemoryStream();
pic.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Byte[] arr = ms.ToArray();
FileStream doesn't support the opening files over the internet.
Try this:
var webClient = new WebClient();
using(var fileStream = webClient.OpenRead("http://www.lokeshdhakar.com/projects/lightbox2/images/image-2.jpg"))
{
byte[] fileContent = new byte[fileStream.Length];
}

Categories

Resources