0

There are word files and pdf files stored in a folder without extensions. When we open these files with pdf view or word viewer the corresponding files gets rendered. Now the requirement is to download these files from .net core application on click of the file name.

Below is the code sample:

public IActionResult Download(int Id)
{
     var fileDetails = GetFileDetailsById(Id);
     string fullpath = Path.Combine(_configuration.GetValue<string>("ServerPath:Documents:FolderPath"), FileNameWithoutExtension);
     List<string> lines = new List<string>();
     StreamReader reader = new StreamReader(fullpath);
     while (!reader.EndOfStream)
     {
         lines.Add(reader.ReadLine());
     }
     byte[] dataAsBytes = lines.SelectMany(s => System.Text.Encoding.UTF8.GetBytes(s + Environment.NewLine)).ToArray();
     var content = new System.IO.MemoryStream(dataAsBytes);
     var contentType = ContentType; // Content ype saved in DB
     var downloadFileName = OriginalFileName;// Original File Name saved in DB
     return File(content, contentType, downloadFileName);
}

value of "fullpath" would be "\foldername\filename" without extension.

When the application is run, the files are downloaded without extension.

I would need help in downloading files with extension.

Progman
  • 16,827
  • 6
  • 33
  • 48
Tarun J
  • 17
  • 4
  • is it possible to save the `OriginalFileName` with the extension when it is first entered into the database. – traveler3468 Mar 26 '22 at 03:01
  • The db has a table which stores file name, extension type and encrypted file name. the file is then stored with the encrypted file name without extension in the folder – Tarun J Mar 26 '22 at 03:04
  • tried the below code: `HttpContext.Response.Clear(); HttpContext.Response.Headers["Content-Disposition"] = string.Format("attachment; filename={0}.{1}", supportingDocument.OriginalFileName, supportingDocument.Content_Type.Extension); HttpContext.Response.ContentType = supportingDocument.Content_Type.Description; HttpContext.Response.SendFileAsync(fileName);` – Tarun J Mar 26 '22 at 03:07
  • instead of reading each line, have you tried reading the files bytes `System.IO.File.ReadAllBytes(FilesPath)` – traveler3468 Mar 26 '22 at 03:08
  • yes @traveler3468. that still downloads the file w/o exxtension – Tarun J Mar 26 '22 at 03:09
  • you will need to add the extension manually by the sounds of it, what does the `OriginalFileName` currently look like? – traveler3468 Mar 26 '22 at 03:10
  • OriginalFileName = "FileName.pdf" – Tarun J Mar 26 '22 at 03:13
  • for pdf files is your `contentType` `application/pdf`? – traveler3468 Mar 26 '22 at 03:14
  • `var contentType = fileDetails.Content_Type.Description;` – Tarun J Mar 26 '22 at 03:16
  • yes it would be `application/pdf` – Tarun J Mar 26 '22 at 03:16
  • can't i use the `HttpContext.Response` object to fix this, it downloads files with extension but only for files of pdf type, files are downloaded with partial contents inside of them. – Tarun J Mar 26 '22 at 03:18
  • so when you download the file and open it in file explorer it is corrupt however the original file is ok? – traveler3468 Mar 26 '22 at 03:19
  • yes.... i'll share the screenshot of the pdf file downloaded when i use the `HttpContext.Response` – Tarun J Mar 26 '22 at 03:20
  • unable to add screenshot here.. – Tarun J Mar 26 '22 at 03:24

1 Answers1

1

Something like this might help point you in the right direction as from the comments it sounds like you're having trouble with downloading a PDF file even with the extension attached.

Use byte[] bytes = System.IO.File.ReadAllBytes(FilesPath)

Once you have done that create a temp file path
string tempPath = Path.Combine(Path.GetTempPath(),$"{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}.pdf");

After that create the temp file using FileStream as well as a BinaryWriter and write the bytes to the BinaryWriter

// Create File Stream,
// Create BinaryWriter So We Can Write A PDF.
using (FileStream fs = new FileStream(tempPath, FileMode.Create))
using (BinaryWriter binaryWriter = new BinaryWriter(fs, Encoding.UTF8))
{
    binaryWriter.Write(bytes);
}

you can then return the tempPath to the caller and read the bytes when required.

If you need to display the PDF in the browser you will need to attach application/pdf to the ContentType in the Response Headers so the browser knows how to handle the request.

traveler3468
  • 1,557
  • 2
  • 15
  • 28