So I've got an MVC 3 application that has a couple places where a text file gets generated and returned in an action using:
return File(System.Text.Encoding.UTF8.GetBytes(someString),
"text/plain", "Filename.extension");
and this works fabulously. Now i've got a situation where I'm trying to return a pair of files in a similar fashion. On the view, i have an action link like "Click here to get those 2 files" and i'd like both files to be downloaded much like the single file is downloaded in the above code snippet.
How can I achieve this? Been searching around quite a bit and haven't even seen this question posed anywhere...
Building on Yogendra Singh's idea and using DotNetZip:
var outputStream = new MemoryStream();
using (var zip = new ZipFile())
{
zip.AddEntry("file1.txt", "content1");
zip.AddEntry("file2.txt", "content2");
zip.Save(outputStream);
}
outputStream.Position = 0;
return File(outputStream, "application/zip", "filename.zip");
Update 2019/04/10:
As #Alex pointed out, zipping is supported natively since .NET Framework 4.5, from JitBit and others:
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
var file1 = archive.CreateEntry("file1.txt");
using (var streamWriter = new StreamWriter(file1.Open()))
{
streamWriter.Write("content1");
}
var file2 = archive.CreateEntry("file2.txt");
using (var streamWriter = new StreamWriter(file2.Open()))
{
streamWriter.Write("content2");
}
}
return File(memoryStream.ToArray(), "application/zip", "Images.zip")
}
Sorry for bumping an old question but...
Another alternative would be to initiate multiple file downloads using JavaScript, and serve files in two different Action Methods on ASP.NET's side.
You're saying you have a link:
On the view, i have an action link like "Click here to get those 2
files"
So make this link like this:
Click to get 2 files
<script src="download.js"></script>
I'm using download.js script found here but you can find plenty of different other options, see this SO question: starting file download with JavaScript for example
I would advice to create a zip file to include both the files using steps(ALGORITHM):
Create a Zip file and add the desired files into the zip
Return the zip file having all desired files from the action
Java Syntax (Just for understanding)
FileOutputStream fos = new FileOutputStream("downloadFile.zip");
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
zos.putNextEntry(new ZipEntry("Filename1.extension"+));
//write data in FileName1.extension
zos.write(contentBuffer1, 0, len);
zos.putNextEntry(new ZipEntry("Filename2.extension"));
//write data in FileName2.extension
zos.write(contentBuffer2, 0, len);
//write other files.....
zos.close();
Once zip file is created, return the newly created zip file to download.
return File("downloadFile.zip");
.DOT Net Equivalent using DotNetZip
var os = new MemoryStream();
using (var zip = new ZipFile())
{
//write the first file into the zip
zip.AddEntry("file1.txt", "content1");
//write the second file into the zip
zip.AddEntry("file2.txt", "content2");
//write other files.....
zip.Save(os);
}
outputStream.Position = 0;
return File(outputStream, "application/zip", "filename.zip");
Hope this helps!
Look at this SO solution: MVC Streaming Zip File
The advantage of this solution is that it streams the file to the client.
I just implemented this solution a couple of days ago and it worked fantastic.
Related
I have upgraded my project from .net framework to .net 6 (core). In my project, there are many places where Bitmap is used. I have read in the microsoft documentations that System.Drawing.Common will only support the Windows platform and even after adding the EnableUnixSupport configuration, it will not be supported in net7.So, now I am using ImageSharp.Web. I have the scenario where I save a file as Image (the format is .tiff) then I read from that path as bitmap and save as PNG ( due to some business rule)
Following is the line of code I am trying change:
Bitmap.FromFile(completePath).Save(pngPath, ImageFormat.Png);
This is the code I have converted into. The only issue is how to save as a new file name as the Tiff file has tiff in the file name.
string extension = _GetExtension(img.ContentType);
if (extension == Constants.TiffExtension)
{
fileName = fileName.Replace(Constants.TiffExtension, "PNG");
using (var outputStream = new FileStream(completePath, FileMode.CreateNew))
{
var image = SixLabors.ImageSharp.Image.Load(completePath);
image.SaveAsync(outputStream, new PngEncoder()); //how to save new file name?
}
}
You can use the image.Save(fileName); overload to save a image to a file. The file name overload that takes just a path will automatically choose the correct encoder based on the file extension.
I was using the ImageSharp.Web package while the one I needed was the basic ImageSharp package. Special thanks to #James South for correcting me and #tocsoft for the guidance.
I have fixed it by the following code which is working:
if (extension == Constants.Conversion.TiffExtension)
{
using (SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(completePath))
{
string pngPath = completePath.Replace(Constants.Conversion.TiffExtension, Conversion.DefaultExtension);
image.Save(pngPath);
fileName = fileName.Replace(Constants.Conversion.TiffExtension, Conversion.DefaultExtension);
}
}
I have an app which saves CSV and my action simply returns a File response. This works perfectly.
public ActionResult GetUserCSV(string returnUrl)
{
var sb = new StringBuilder();
var users = context.Users.ToList();
sb.AppendLine("Username,Firstname,Lastname");
foreach (var u in users)
{
sb.AppendLine(String.Format("{0},{1},{2}", u.username, u.firstname, u.lastname));
}
string csv = sb.ToString();
var data = Encoding.UTF8.GetBytes(csv);
string filename = "users.csv";
return File(data, "text/csv", filename);
}
I really wanted to save as xslx and I recently found EPPLUS and this tutorial
here which uses a similar approach.
I have copied the tutorial exactly as a test in to my MVC app. It creates the excel file perfectly, however my Mcafee site advisor keeps telling me that the download is dangerous. I have changed the data to data in my db and it is still giving me the same warning.
Am I missing something, or does EPPlus create excel files with inappropriate content?
I wondered if it was the mimetype but I checked and this does appear to be correct.
Has anyone ever experienced this
Uninstall McAfee and use a better AV.
I am using a .txt file to log exceptions thrown from various methods in my asp.net (4.0) project. I have a page which reads texts from that file on every 10 minutes. If there are Read and Write attempts at the same time, will it throw any exception? If you have any better technique to handle such problem, please let me know. Currently, i'm using the following code-
Writing to the file
using (StreamWriter Writer = new StreamWriter(LogFilePath, true))
{
Writer.WriteLine(ErrorMsg);
}
Reading from the file
using (FileStream fs=File.OpenRead(LogFilePath))
{
using (StreamReader reader = new StreamReader(fs))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Response.Write(line + "</br>");
}
}
}
Is these approaches are safe?
Thank you.
As people already suggested, the simplest way is to use external libraries, which handle locking of the file.
However, if you still want to use your own code to do that, make sure you're synchronizing access to the file, using lock:
lock(lockObj)
{
using (StreamWriter Writer = new StreamWriter(LogFilePath, true))
{
Writer.WriteLine(ErrorMsg);
}
}
where lockObj is
static object lockObj = new object();
I have some code written by another person. It's uploading a file to a server. I want to post simillar request but without sending a file (my version will copy file of a given name). I can't use method file.Upload(...). So what function I can use?
This is a code of request with file:
var request:URLRequest = new URLRequest(ApiConfig.ApiUrl);
request.method = URLRequestMethod.POST;
request.data = params;
try
{
_fileRef.upload(request);
}
catch(error:Error)
{
Alert.show(error.message);
}
I simply whant to make simillar request, but without uploading file and not using file instance.
I think it's pretty much dumb question but I don't know how to do this.
Hey Guys I have a database with field
Name,Email,Contact,Address,Profile And I have created a excel sheet with
these field & data in it (100 entry).
Now i want to use File-upload Control for browsing these excel sheet & on click of Button Control it automatically fill excel sheet data into database.
So anybody who has a idea kindly share with me. I try over it a lot but doesn't reach to solution. So please kindly share your valuable guidance.
Take a look at the Excel Data Reader project. With this you can very easily dump an Excel file (either older binary format or newer OpenXML format) into a DataSet, at which point you can do whatever you want with the data. Here's some sample code I used as a proof of concept in a previous project:
private static DataSet ImportDataFromExcelFile()
{
DataSet dataFromExcelFile = null;
// Try importing the file as OpenXML
using (var excelFile = File.Open(excelFileName, FileMode.Open, FileAccess.Read))
{
using (var excelReader = ExcelReaderFactory.CreateOpenXmlReader(excelFile))
{
excelReader.IsFirstRowAsColumnNames = true;
dataFromExcelFile = excelReader.AsDataSet();
}
}
if (dataFromExcelFile != null)
return dataFromExcelFile;
// Try importing the file as Excel 97-2003
using (var excelFile = File.Open(excelFileName, FileMode.Open, FileAccess.Read))
{
using (var excelReader = ExcelReaderFactory.CreateBinaryReader(excelFile))
{
excelReader.IsFirstRowAsColumnNames = true;
dataFromExcelFile = excelReader.AsDataSet();
}
}
if (dataFromExcelFile != null)
return dataFromExcelFile;
throw new Exception("Unable to determine format of Excel file.");
}
First it tries to read the Excel file in the more modern format. If that fails, it tries in an older format. If that fails, it gives up and throws an exception.