I have been following these links all listed below, i found the best way to write this SMALL create Excel and Download function. ( Using EPPlus for Excel )
Download file of any type in Asp.Net MVC using FileResult? + How to convert an Stream into a byte[] in C#?
Using a FileStreamResult with a MemoryStream in ASP.NET MVC 3
Writing A Custom File Download Action Result For ASP.NET MVC
It runs through the code perfectly without error every time I run this but does not "Kick out" the file to be downloaded ( in a save as dialogue or w/e ).
public ActionResult ShowReport()
{
using (var stream = new MemoryStream())
{
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("Sample1");
ws.Cells["A1"].Value = "Sample 1";
ws.Cells["A1"].Style.Font.Bold = true;
var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
shape.SetPosition(50, 200);
shape.SetSize(200, 100);
shape.Text = "Sample 1 text text text";
var fileDownloadName = "sample.xlsx";
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";//System.Net.Mime.MediaTypeNames.Application.Octet
var fileStream = new MemoryStream();
pck.SaveAs(fileStream);
fileStream.Position = 0;
var fsr = new FileStreamResult(fileStream, contentType);
fsr.FileDownloadName = fileDownloadName;
byte[] fileBytes = ReadToEnd(fileStream);
string fileName = "example";
return File(fileBytes, contentType, fileName);
}
}
What am I doing wrong / missing? - Must i write that Dialogue myself?
PN: I have also attempted this way
byte[] fileBytes = ReadToEnd(fileStream);
string fileName = "example";
return File(fileBytes, contentType, fileName);
ofcourse i had to figure out how to convert Stream to Byte but it also did not show anything.
Image of Chrome's Network Development Tool
Sorry about the small image ( if you can't see it scroll in with ctl+MouseWheel ) if your in a supporting browswer.
(In response to the comment thread above.)
From the image posted it looks like the actual file request (the last one in the list) is coming from JavaScript code instead of from a normal document-level request. Given this, it's highly likely that the server-side code is working correctly and returning the correct response.
However, since it's an AJAX request, the browser doesn't actually know what to do with the response. There are some potential solutions here. Ideally, you'll want to make this a normal request and remove AJAX from the picture if possible. If that's not an option, you can still initiate a document-level request from JavaScript. Something as simple as this:
window.location = '#Url.Action("Method", "Controller")';
This would be initiated from JavaScript code as it currently is, but would be for the whole browser instead of an AJAX request. That should do the trick.
Using the memory stream you have you can simple pass that to the Response object once you have saved the Excel Package
Code:
Response.AddHeader("content-disposition", "attachment;filename=FILENAME.xlsx")
Response.Charset = String.Empty
Response.ContentType = "application/ms-excel"
Response.BinaryWrite(stream.ToArray())
Response.End()
Related
I want to display a pdf. My current code displayit using a pdf reader. But I want to open it in a seperate tab of the browser. How can i do it? I have a link button inside the web page. I have set this in onClick method. How to open it using back end code? (not using a link in aspx)
Here is my code
string name = ddlAppealList.SelectedValue.ToString();
int refNo = Convert.ToInt32(name);
string FilePath = Server.MapPath("~/filesPDF/" + refNo + ".pdf");
WebClient User = new WebClient();
Byte[] FileBuffer = User.DownloadData(FilePath);
if (FileBuffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", FileBuffer.Length.ToString());
Response.BinaryWrite(FileBuffer);
}
Response.ContentType = "Application/pdf";
Response.TransmitFile(PDFfilepath);
For opening the PDF file in a new tab or windows you can use following html code:
View
I hope it helps you.
I encountered a similar situation a few weeks ago. This piece of code, inspired by this answer, helped me solve the issue:
Response.AppendHeader("Content-Disposition", new System.Net.Mime.ContentDisposition { Inline = true, FileName = "pdfname.pdf" }.ToString());
Here is an example to open a pdf in a C# web application with ActionResult. You can also store the pdf as a byte[] in the database to make this code simpler.
public async Task<ActionResult> ViewPdf()
{
MemoryStream ms = new MemoryStream();
FileStream stream = new FileStream("mypdf.pdf", FileMode.Open, FileAccess.Read);
stream.CopyTo(ms);
return File(ms.ToArray(), "application/pdf");
}
I'm trying to make some sort of download service for a school project. Concept is simple - create a zip file from uploaded files. First problem is asp.net on school server is configured that apps cannot write any files, so I'm storing them in database. Then I need to create zip from these. Again, no writing on disk. I managed to get it to work. Almost - the code produces corrupted file.
Fun fact is that commented part produces working file. The difference is in 11th and 12th byte. It seems to be checksum or file length, but in corrupted file it is different each time.
The solution to this problem is using DotNetZip lib, but I think it is a matter of one line or something, because there are only 2 bytes wrong. (Bytes 12-15 correspond to modification date and time, so they had to be different. I'm not sure why my editor didn't show me that there's chunk of data missing at the end).
Corrupted file is missing a signature at the end. It may be caused by wrong content length header or zip generation.
using (var memoryStream = new MemoryStream())
{
// var filepath = context.Server.MapPath("files\\") + Guid.NewGuid() + ".zip";
// var zip = ZipFile.Open(filepath, ZipArchiveMode.Create);
var mzip = new ZipArchive(memoryStream, ZipArchiveMode.Create);
while (reader.Read())
{
//zip.CreateEntryFromFile((string) reader["path"], (string) reader["name"], CompressionLevel.Optimal);
var contents = (byte[]) reader["contents"];
var stream = mzip.CreateEntry((string) reader["name"], CompressionLevel.Optimal).Open();
using (var fs = new MemoryStream(contents))
{
fs.CopyTo(stream);
}
stream.Close();
}
// zip.Dispose();
Response.Clear();
Response.ContentType = "application/ocetet-stream";
Response.HeaderEncoding = Response.ContentEncoding;
Response.AppendHeader("content-disposition", "attachment; filename=\"" + gname + ".zip\"");
//Response.AppendHeader("content-length", new FileInfo(filepath).Length.ToString());
Response.AppendHeader("content-length", memoryStream.Length.ToString());
// Response.TransmitFile(filepath);
Response.BinaryWrite(memoryStream.ToArray());
Response.Flush();
}
Also - I'm new to C#, so my code may be pretty bad.
I have some EML Files with attachments. I've parsed the EML files pulled out the attachments, and if I do this :
File.WriteAllBytes(attachment.Name, Convert.FromBase64String(attachment.Data))
I get the attachment dumped to a file. What I want to do is have a link so that when the user clicks on it, the attachment downloads.
Easy enough if its a file already on disk, but instead I have this base64encoded string that I can convert to a byte array. How can I take this base64encoded string (or the converted byte array) and generate a link directly to that?
Thanks
You would return back a FileResult class with the data from some other action method:
public ActionResult DownloadData(string fileNameOrWhatever)
{
byte[] fileData = ...;
return File(fileData, "someMimeType", "downloadNameToBeDisplayed");
}
Your link would then point here:
Click me!
Is this MVC? You can create a controller method that returns a FileStreamResult, create an action to link to it and write the data in.
I have a project where I create an Excel document on the server and the user will receive the file as a download when they navigate to the specific action. Here's the code I'm using, and I think you can refactor it for what you need:
public void GetExcel(string id)
{
ExcelPackage p = new ExcelPackage();
//code to add data to the document
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=BitlyReport.xlsx");
MemoryStream stream = new MemoryStream(p.GetAsByteArray());
Response.OutputStream.Write(stream.ToArray(), 0, stream.ToArray().Length);
Response.Flush();
Response.Close();
}
Basically I wan't to save an image loaded in a webBrowser control. The only way I can get this to work at the moment is by showing the save as dialog.
is there a way to pass in a path and make it save itself? (hide the dialog I ask to show!)
is there another way to save the image? I can't seem to get documentstream to work. I have also tried webclient.filedownload(...) but get an error 302 ( "(302) Found Redirect.")
DownloadFileAsync gives no error but an empty jpeg file?
files are always jpegs, but not always at same location.
You should go with HttpWebRequest.
It has the capability to follow a 302 automatically.
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
//increase this number if there are more then one redirects.
myHttpWebRequest.MaximumAutomaticRedirections = 1;
myHttpWebRequest.AllowAutoRedirect = true;
var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
var buff = new byte[myHttpWebResponse.ContentLength];
// here you specify the path to the file. The path in this example is : image.jpg
// if you want to store it in the application root use:
// AppDomain.CurrentDomain.BaseDirectory + "\\image.jpg"
using (var sw = new BinaryWriter(File.Open("c:\\image.jpg", FileMode.OpenOrCreate)))
{
using (var br = new BinaryReader (myHttpWebResponse.GetResponseStream ()))
{
br.Read(buff, 0, (int)myHttpWebResponse.ContentLength);
sw.Write(buff);
}
}
I've got the problem as below:
There is some SOAP web service which allows to read stream files. I need to read the whole file divided to chunks and transmit to user. All actions should do not block UI main thread: user presses 'Save' button on save file dialog, and is able to move on to the next page or perform another action. I will be grateful for the sample solution. Note that the solution should work with IIS 5.1.
Regards,
Jimmy
Downloading a file in ASP.NET byte-by-byte to the response page. check at msdn about this:
try
{
System.String filename = "C:\\downloadJSP\\myFile.txt";
// set the http content type to "APPLICATION/OCTET-STREAM
Response.ContentType = "APPLICATION/OCTET-STREAM";
// initialize the http content-disposition header to
// indicate a file attachment with the default filename
// "myFile.txt"
System.String disHeader = "Attachment;
Filename=\"myFile.txt\"";
Response.AppendHeader("Content-Disposition", disHeader);
// transfer the file byte-by-byte to the response object
System.IO.FileInfo fileToDownload = new
System.IO.FileInfo(filename);
System.IO.FileStream fileInputStream = new
System.IO.FileStream(fileToDownload.FullName,
System.IO.FileMode.Open, System.IO.FileAccess.Read);
int i;
while ((i = fileInputStream.ReadByte()) != - 1)
{
Response.Write((char)i);
}
fileInputStream.Close();
Response.Flush();
Response.Close();
}
catch (System.Exception e)
// file IO errors
{
SupportClass.WriteStackTrace(e, Console.Error);
}
There are some articles that may help you to implement and solve errors:
download an excel file from byte() on https server
asp.net downloading file from ftp getting it as byte[] then saving it as file
Remote file Download via ASP.NET corrupted file
Response.WriteFile cannot download a large file
ProcessRequest method form downloader HttpHandler:
public void ProcessRequest(HttpContext context)
{
RequestTarget target = RequestTarget.ParseFromQueryString(context.Request.QueryString);
Guid requestId = new Guid(context.Request.QueryString["requestId"]);
string itemName = HttpUtility.UrlDecode(context.Request.QueryString["itemName"]);
if (target != null &&
!requestId.Equals(Guid.Empty) &&
!string.IsNullOrEmpty(itemName))
{
HttpResponse response = context.Response;
response.Buffer = false;
response.Clear();
response.AddHeader("Content-Disposition", "attachment;filename=\"" + itemName + "\"");
response.ContentType = "application/octet-stream";
int length = 100000, i = 0;
byte[] fileBytes;
do
{
fileBytes = WS.ReadFile(requestId, target, i * length, length);
i++;
response.OutputStream.Write(fileBytes, 0, fileBytes.Length);
response.Flush();
}
while (fileBytes != null && fileBytes.Length == length);
}
}
The whole problem is not to organize download action, but satisfy the condition that download action should do not block UI main thread: user presses 'Save' button on save file dialog, and is able to move on to the next page or perform another action. The solution written by Niranjan Kala causes, when the file is very large user isn't able to see another page until the download action has completed. I appreciate it, but it's not what I meant ...
If I understand you correctly, you want to make the browser initiate a new request for the file without reloading the current page. The easiest approach is probably to just create a link with target="_blank". Something like this should do:
Download file
If you provide a content type of application/octet-stream most browsers will save the file to disk.