I am working with a c# web api controller, where my code is supposed to create several word documents and zip them into a zip file. I am using Ionic.Zip to zip the file and return it to the code below as the input parameter.
The code is supposed to push the zip file to the user to download, but it is loading the zip file in a window instead.
I am using the following code:
protected HttpResponseMessage ZipContentResult(ZipFile zipFile)
{
// inspired from http://stackoverflow.com/a/16171977/92756
var pushStreamContent = new PushStreamContent((stream, content, context) =>
{
zipFile.Save(stream);
stream.Close(); // After save we close the stream to signal that we are done writing.
}, "application/zip");
return new HttpResponseMessage(HttpStatusCode.OK) {Content = pushStreamContent};
}
But when I run it, the zip file loads into the window instead of prompting to save the file.
this is what I get when I run it:
PKxS�I$$filedocumentname.docx
�0�L�G#.�L�G#.�L���UP#�-JB��ew.
�\��u��$8��;0�\w�����Su�s��y��z��U�]�ת���*�3r,�L6zy4�O00>`a`�a�xj���i��i���f�a��������S��O1���F��pQ�x�R��
�W�ȟ<vJS�8ZTGCZ�Y/....
any ideas of what I am doing wrong or how to fix this?
much appreciated.
Related
I have been using method in which I am taking data in bytes then creating zip file and then uploading it back to required location but I need something which is efficient. I am also using this ICSharpZipLib library mentioned on this page link to perform the action but I couldn't understand this piece of code HttpResponseBase response in function parameter.
This is how my FileShareCode looks like:
var shareClient = Common.CreateSMBClientFromConnectionString(shareName, storageConnectionString);
ShareDirectoryClient directory = shareClient.GetDirectoryClient(dirName);
ShareFileClient file = directory.GetFileClient(fileName);
I am trying to replace HttpResponseBase response with ShareFileClient file.URI but it doesn't work.
I'm quite new to using RestSharp and I've got a question that I can't find an answer to here on SO.
I've have this situation where I must download a csv-file and output the file directly in the browser. The following code illustrates how to download a file and save it to a certain path on disc.
string tempFile = Path.GetTempFileName();
using (var writer = File.OpenWrite(tempFile))
{
var client = new RestClient(baseUrl);
var request = new RestRequest("Assets/LargeFile.7z");
request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer);
var response = client.DownloadData(request);
}
I want to download the csv-file and directly output the result as a download file in the browser. You know, like in Chrome the file you download will be displayed in the left bottom corner of your browser.
Can this be done using RestSharp? And if so, how? Got an example? Please share it. ;-)
Thanx!
I'm fetching an object from couchbase where one of the fields has a file. The file is zipped and then encoded in base64.
How would I be able to take this string and decompress it back to the original file?
Then, if I'm using ASP.MVC 4 - How would I send it back to the browser as a downloadable file?
The original file is being created on a Linux system and decoded on a Windows system (C#).
You should use Convert.FromBase64String to get the bytes, then decompress, and then use Controller.File to have the client download the file. To decompress, you need to open the zip file using some sort of ZIP library. .NET 4.5's built-in ZipArchive class should work. Or you could use another library, both SharpZipLib and DotNetZip support reading from streams.
public ActionResult MyAction()
{
string base64String = // get from Linux system
byte[] zipBytes = Convert.FromBase64String(base64String);
using (var zipStream = new MemoryStream(zipBytes))
using (var zipArchive = new ZipArchive(zipStream))
{
var entry = zipArchive.Entries.Single();
string mimeType = MimeMapping.GetMimeMapping(entry.Name);
using (var decompressedStream = entry.Open())
return File(decompressedStream, mimeType);
}
}
You'll also need the MIME type of the file, you can use MimeMapping.GetMimeMapping to help you get that for most common types.
I've used SharpZipLib successfully for this type of task in the past.
For an example that's very close to what you need to do have a look here.
Basically, the steps should be something like this:
you get the compressed input as a string from the database
create a MemoryStream and write the string to it
seek back to the beginning of the memory stream
use the MemoryStream as an input to the SharpZipLib ZipFile class
follow the example provided above to unpack the contents of the ZipFile
Update
If the string contains only the zipped contents of the file (not a full Zip archive) then you can simply use the GZipStream class in .NET to unzip the contents. You can find a sample here. But the initial steps are the same as above (get string from db, write to memory stream, feed memory stream as input to the GZipStream to decompress).
Using the DotNetZip Library (http://dotnetzip.codeplex.com/) is there a way to move files from one zip file into another without extracting that file to disk first? Maybe extract to a stream, then update into the other zip from that same stream?
The zip files are password protected and the data in these zip files are meant to stay that way due to their licenses. If I simply extract to disk first then update the other zip there is a chance where those files can be intercepted by the user.
Yes, you should be able to do something like;
var ms = new MemoryStream();
using (ZipFile zip = ZipFile.Read(sourceZipFile))
{
zip.Extract("NameOfEntryInArchive.doc", ms);
}
ms.Seek(0);
using (ZipFile zip = new ZipFile())
{
zip.AddEntry("NameOfEntryInArchive.doc", ms);
zip.Save(zipToCreate);
}
(see it as pseudocode since I didn't have a chance to compile)
Naturally you'll have to add your decryption/encryption to that, but those calls are equally straight forward.
I've produced a MVC app that when you access /App/export it zips up all the files in a particular folder and then returns the zip file. The code looks something like:
public ActionResult Export() {
exporter = new Project.Exporter("/mypath/")
return File(exporter.filePath, "application/zip", exporter.fileName);
}
What I would like to do is return the file to the user and then delete it. Is there any way to set a timeout to delete the file? or hold onto the file handle so the file isn't deleted till after the request is finished?
Sorry, I do not have the code right now...
But the idea here is: just avoid creating a temporary file! You may write the zipped data directly to the response, using a MemoryStream for that.
EDIT Something on that line (it's not using MemoryStream but the idea is the same, avoiding creating a temp file, here using the DotNetZip library):
DotNetZip now can save directly to ASP.NET Response.OutputStream.
I know this thread is too old , but here is a solution if someone still faces this.
create temp file normally.
Read file into bytes array in memory by System.IO.File.ReadAllBytes().
Delete file from desk.
Return the file bytes by File(byte[] ,"application/zip" ,"SomeNAme.zip") , this is from your controller.
Code Sample here:
//Load ZipFile
var toDownload = System.IO.File.ReadAllBytes(zipFile);
//Clean Files
Directory.Delete(tmpFolder, true);
System.IO.File.Delete(zipFile);
//Return result for download
return File(toDownload,"application/zip",$"Certificates_{rs}.zip");
You could create a Stream implementation similar to FileStream, but which deletes the file when it is disposed.
There's some good code in this SO post.