FIle Downloading asp.net - c#

I am trying to download a file using a button on asp.net, but the button gives me the webform aspx as the the downloaded file in my case DownloadFileTest.apsx. I needed to download the right file. This might help I the uploaded file in my solution explorer doesn't show up either. But it shows up if I access it inside the folder of my project. Here is the code
protected void Button1_Click(object sender, EventArgs e)
{
string filename = TextBox1.Text;
Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-diposition", "attach;filename" + filename);
Response.TransmitFile(Server.MapPath("~/CustomerFiles/" + filename));
Response.End();
}

This is the code I use to download file, make sure fuldFilNavn contains the full path of the file:
public static void DownloadFil(string fuldFilNavn)
{
HttpContext context = HttpContext.Current;
context.Response.ClearHeaders();
context.Response.ClearContent();
string filNavn = Uri.EscapeDataString(Path.GetFileName(fuldFilNavn)).Replace("+", "%20");
context.Response.AppendHeader("Content-Disposition", "attachment;filename*=utf-8''" + filNavn);
context.Response.AppendHeader("Last-Modified", File.GetLastWriteTimeUtc(fuldFilNavn).ToString("R"));
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Length", new FileInfo(fuldFilNavn).Length.ToString());
context.Response.TransmitFile(fuldFilNavn);
context.Response.End();
}
This will download files with unicode characters in the filename!

You may try the following ASP.NET/C# code snippet:
internal static void Download(string FileName)
{
HttpResponse _response = HttpContext.Current.Response;
FileStream _fileStream;
byte[] _arrContentBytes;
try
{
// clear response obj
_response.Clear();
// clear content of response obj
_response.ClearContent();
// clear response headers
_response.ClearHeaders();
// enable response buffer
_response.Buffer = true;
// specify response content
_response.ContentType = ContentType;
_response.StatusCode = 206;
_response.StatusDescription = "Partial Content";
// create FileStream: IMPORTANT - specify FileAccess.Read
_fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
// Bytes array size= (int)_fs.Length;
_arrContentBytes = new byte[(int)_fileStream.Length];
// read file into bytes array
_fileStream.Read(_arrContentBytes, 0, (int)_fileStream.Length);
// add response header
_response.AddHeader("content-disposition", "attachment;filename=" + FileName);
// ACTUAL PROCEDURE: use BinaryWrite to download file
_response.BinaryWrite(_arrContentBytes);
// ALTERNATIVE: TransmitFile
//_response.TransmitFile(filePath);
// close FileStream
_fileStream.Flush();
_fileStream.Close();
_response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch { }
finally
{
_fileStream = null;
_arrContentBytes = null;
}
}
In order to get the root folder and full path you may use Server.MapPath as in your original solution or the following line for better performance:
// get the root dir; fast
string _root = AppDomain.CurrentDomain.BaseDirectory;
This solution has been tested/implemented in the actual web app (http://taxiom.com/Manual_Payday.aspx) - refer to the "Download" button in the upper-right corner of the page for the demo. Hope this may help.

Related

Why is my file downloading only when I click retry .net core

I'm trying to export data from database to an excel file and then download that file on client side. The export works fine but the problem is with the download part. Every time I call the method "DownloadCurrent" I get failed attempt in the browser. But if I click on retry (circle arrow) in browser then it downloads the file with no problem.
Code :
...
string fileName = className + "Export.xlsx";
string filePath = Directory.GetCurrentDirectory() + "\\wwwroot\\" + fileName;
public void DownloadCurrent(String filePath, String fileName)
{
WebClient client = new WebClient();
Byte[] buffer = client.DownloadData(filePath);
if (buffer != null && buffer.Length > 0)
{
Response.ContentType = "application/vnd.ms-excel";
Response.Headers.Add("content-length", buffer.Length.ToString());
Response.Headers.Add("content-disposition", "attachment; filename=" + fileName);
Response.Body.Write(buffer);
}
}
I'm using VS 2022, and .NET 6.0
ASP.NET Core Web App
As stated in a comment above, don't use WebClient anymore.
However, based on your code, you don't need to use either WebClient or HttpClient. It appears your file is a local file that you simply need to stream to the browser. The only reason I see that you would need to use a WebClient or HttpClient for this, is if that file needs to be first downloaded from a remote server via a URI, for example.
Something like this code should do the trick:
public void DownloadCurrent(String filePath, String fileName)
{
using FileStream fs = File.OpenRead(filePath);
long length = fs.Length;
byte[] buffer = new byte[length];
fs.Read(buffer, 0, (int)length);
Response.ContentType = "application/vnd.ms-excel";
Response.Headers.Add("content-length", length.ToString());
Response.Headers.Add("content-disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(buffer);
}
For more, please see: https://learn.microsoft.com/en-us/dotnet/api/system.web.httpresponse.binarywrite?view=netframework-4.8.

How to delete exist Excel file from uploaded folder?

How to close excel file or delete from folder. I tried a lot but its not getting file there.so always throwing error : The process cannot access the file because it is being used by another process.How to solve it?
first time not throwing any error .going successfully uploaded but when next time with same file i am trying to upload then imideatly throwing an error before call upload method
creating excel
System.Data.DataTable dtexcel = new System.Data.DataTable();
dtexcel = BindComboWithParm("Get_Cols_Forexcelsheet");
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dtexcel, "Customer");
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=Customer_Creation.xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
checking for file
string FileName = "Customer_Creation";
string Paths = Server.MapPath("~/Uploads/") + FileName;
FileInfo file = new FileInfo(Paths);
if (file.Exists)
{
file.Delete();
}
upload event click
protected void btnUpload_Click(object sender, EventArgs e)
{
try
{
string FileName = "Customer_Creation";
string Paths = Server.MapPath("~/Uploads/") + FileName;
FileInfo file = new FileInfo(Paths);
if (file.Exists)
{
file.Delete();
}
if (FileUpload1.HasFile)
{
string excelPath = Server.MapPath("~/Uploads/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
FileUpload1.SaveAs(excelPath);
ImporttoSQL(excelPath);
}
else
{
ScriptManager.RegisterClientScriptBlock(Page, typeof(System.Web.UI.Page), "ClientScript", "alert('Please select Excelsheet')", true);
return;
}
}
catch (Exception ex)
{
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alert", "alert('Exception Message: " + ex.Message.Replace("'", "").Replace("\"", "") + "');", true);
}
finally
{
ViewState["ExcelUploaded"] = "false";
}
}
I believe you just want to create a file, download it and then delete it once it has downloaded.
1. Create a custom FileHttpResponseMessage.
public class FileHttpResponseMessage : HttpResponseMessage
{
private readonly string filePath;
public FileHttpResponseMessage(string filePath)
{
this.filePath = filePath;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
Content.Dispose();
if(File.Exist(filePath))
File.Delete(filePath);
}
}
2. Create a function which will return generated file path. and use that path in below code :
public HttpResponseMessage Get()
{
var filePath = GetNewFilePath();//your function which will create new file.
var response = new FileHttpResponseMessage(filePath);
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(new FileStream(filePath, FileMode.Open, FileAccess.Read));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName ="YourCustomFileName"
};
return response;
}
3. Above code will delete file automatically once file will be served to user.
Right now it's difficult to say what is wrong. Most likely your file is still in use by some part of your program. Pleases check this link it contains useful information about how to debug it.
Your app has uploaded a file to a server. For this purpose it used managed resources (like FileStream etc). For some reason this file remains opened. Later your app tries to delete it when it's still in use. And you get this "File in use" exception.
What i'd recommend to do is try to delete this file directly and if this works then the problem is hidden somewhere in your 'upload part' of your code. If its not then problem is most likely lay with some external processes that uses this file.

Open HttpResponse in a new tab

I have the following case.
I am creating a filestream from a pdf file.
after the reponse the generated PDF will be opened in the same tab to print, save etc.
The question is: HOW DO I CHANGE THIS CODE SO IT WILL OPEN IN A NEW TAB (OR WINDOW)?
string filepath = String.Format(*Path to file*);
string filename = *Filename*;
try
{
FileStream fs = new FileStream(filepath, FileMode.Open);
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
var docLength = fs.Length;
fs.Close();
WebClient req = new WebClient();
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.BufferOutput = true;
Response.ContentType = "Application/pdf";
response.AddHeader("content-disposition", "inline; filename=" + filename);
response.AddHeader("Content-Length", docLength.ToString());
//response.Write("<script>");
//response.Write("window.open('" + filepath + "',_newtab');");
//response.Write("</script>");
byte[] data = req.DownloadData(filepath);
response.BinaryWrite(data);
}
catch (Exception ex)
{
// Here I log the exception to a text file.
}
finally
{
HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
HttpContext.Current.Response.SuppressContent = true; // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
}
I have tried several options, but still not found a solution that works for me.
Can someone help me with this.
This function is not directly triggered by a button.
the button triggers another method which generates some other stuff and after that it triggers the method described above.
Response.Write("<script>");
Response.Write("window.open('../LOCATION/pages/FILENAME.pdf', '_newtab');");
Response.Write("</script>");

I made csv file on the server - how can I let the client download this file?

I have made csv on the server like this:
string Expath = #"d:\A.csv";
protected void Button3_Click(object sender, EventArgs e)
{
FileStream FS = null;
StreamWriter SW = null;
try
{
FS = new FileStream(Expath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
SW = new StreamWriter(FS, Encoding.Default);
SW.WriteLine("Test");
SW.WriteLine("1,2,3,4,5");
}
catch { }
finally
{
if (SW != null)
{
SW.Close();
FS.Close();
}
}
}
is it correct to make this file on d: on the server? if not where is better to place hem?
how do to that the client can download this file after he made it? (asp.net C#)
You could use this code to push the file to browser.
private void PushToBrowser(string FilePath, byte[] Data)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.BufferOutput = true;
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ContentType = #"application/csv";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(FilePath));
HttpContext.Current.Response.OutputStream.Write(Data, 0, Data.Length);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Close();
File.Delete(FilePath);
}
You could use the following code to convert you text data to byte array
byte[] Data = File.ReadAllBytes(FilePath)
I won't recommended keeping generated files outside the web directory, even though its possible to write to a directory outside the web root in ASP.NET through impersonation, but its not at all recommended on production enviornment.
Probably d:\ is not a so good place. If you have a web server running on that server, you have to see where the Virtual Directory of the site in which you intend publish the file is located, and then put the file somewhere here.
When I have made files on the server, eg images I have saved to
Server.MapPath(#"~\" + sFilename)

Recreating a new PDF still holds the old Image, using ASP.NET, C# and Winnovative.WnvHtmlConvert.PdfConverter

If I build a PDF (pdf1) with an image(image1), pdf1 shows image1 as expected.
If I then replace image1 with image2, in the site, and make a new pdf2, pdf2 shows the old image1, and that's my (caching?) problem.
For more information:
If I stop my program in VS and close all my Development Servers (Local ISS?), run the program again and make a new pdf (pdf3), the pdf3 shows the image2(the last image i made), which is correct.
So I guess i dont end some things or cache to much?
How I create the PDF
public void CreateSingleFrontpage(string url)
{
var pdfConverter = new PdfConverter(0);
PdfConverter.LayoutHtmlTimeoutSec = 500;
pdfConverter.NavigationTimeout = 5000;
pdfConverter.LicenseKey = "****************************";
pdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
pdfConverter.PdfDocumentOptions.PdfCompressionLevel =
PdfCompressionLevel.Normal;
pdfConverter.PdfDocumentOptions.PdfPageOrientation =
PDFPageOrientation.Portrait;
pdfConverter.PdfDocumentOptions.ShowHeader = false;
pdfConverter.PdfDocumentOptions.ShowFooter = false;
pdfConverter.PdfDocumentOptions.LeftMargin = 80;
pdfConverter.PdfDocumentOptions.RightMargin = 40;
byte[] pdfBytes = pdfConverter.GetPdfBytesFromUrl(url);
// send the PDF document as a response to the browser for download
System.Web.HttpResponse response =
System.Web.HttpContext.Current.Response;
response.Clear();
// response.CacheControl = "no-cache";
response.AddHeader("Content-Type", "binary/octet-stream");
response.AddHeader("Content-Disposition", "attachment;
filename=PDF_Temp.pdf; size=" + pdfBytes.Length);
response.Flush();
response.BinaryWrite(pdfBytes);
response.Flush();
response.End();
}
ProcessRequest
public void ProcessRequest(HttpContext context)
{
int skemaId = int.Parse((context.Request.QueryString["SkemaId"]));
int witchImage = int.Parse(context.Request.QueryString["witchImage"]);
byte[] imageData = new BLL.Handlers.PDFForsideHandlers().GetImage(
witchImage, skemaId);
if (imageData != null)
{
context.Response.ContentType = "image/jpg";
context.Response.BinaryWrite(imageData);
// context.Response.Flush();
// context.Response.Clear();
// context.Response.Close();
// context.Response.End();
}
}
asp.net control
Image image = new Image();
image.ImageUrl = url;
image.DataBind();
PlaceHolder1.Controls.Add(image);
I spend a whole day on this now, any comments would be much appriciated.
Winnovative is grabbing the image from the cached under C:\Windows\Temp\Temporary Internet Files\Content.IE5 for IE9. This "windows" ie cache directory is different based on your version of IE.
It turnes out that it worked on another computer. So it must be my FF and Chrome settings or the function the browser has to handles PDF's that's no good. If anyone else care..

Categories