1

I am having a problem when downloading the content after I uploaded the file using FormData in JavaScript XMLHttpRequest and connect to Web API and save it to MySQL DB as LONGBLOB data type. When I tried to download the file that is being uploaded previously as BLOB to MySQL DB, the file is being downloaded, however the file cannot be readable anymore. Any solutions?

Here is the code that I am using for uploading the file to the DB as byte array:

  • HTML and Javascript:
<input id="Upload" type="file" accept="application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf" />
let SubmittedData = new FormData();
let XHR = new XMLHttpRequest();

SubmittedData.append("FileContent", $("#Upload").files[0]);

XHR.open("POST", "/UploadFile");
XHR.send(SubmittedData);
XHR.onreadystatechange = function () {
    if (XHR.readyState == 4 && XHR.status == 200)
        alert("Success");
}
  • Web API:
[HttpPost]
public ActionResult UploadFile()
{
    if (Request.Files.Count <= 0)
        return Ok();

    byte[] FileContent = new byte[0];

    using (var reader = new BinaryReader(Request.Files[0].InputStream))
        FileContent = reader.ReadBytes(Request.Files[0].ContentLength);

    InsertToMySQLDB(FileContent);

    return Ok()
}

Here is the code that I am using for retrieve the byte array from DB and download it as PDF (I am using HtmlToPDF library in NuGet for downloading as PDF) and Word:

public ActionResult DownloadPDF()
{
    byte[] FileContent = RetrieveFileContentFromMySQLDB();

    return File(FileContent, "application/pdf", "File.pdf");
}

public ActionResult DownloadWord()
{
    byte[] FileContent = RetrieveFileContentFromMySQLDB();

    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("Content-Disposition", $"attachment;filename=File.doc");
    Response.Charset = string.Empty;
    Response.ContentType = "application/vnd.ms-word";
    Response.Output.Write(Encoding.Default.GetString(FileContent, 0, FileContent.Length));
    Response.Flush();
    Response.End();
    break;
)

EDIT:

There is another problem now, the scenario is:

  • When I upload the PDF file and download it as PDF, it can be downloaded and the content is same like what I have been uploaded before, however when I tried to download it as Word, it is being downloaded, but the content is just all hex characters.

  • When I upload the Word file and download it as PDF, it cannot be downloaded (the file is corrupted), and when I download it as Word, it is being downloaded, but the content is just all hex characters.

Any solutions for the conversion?

Thank you very much

Sky
  • 13
  • 3
  • Could you show the `left(hex(id),16)` that will be returned by MySQL when selecting the blob, to verify the PDF is stored correctly? (see: [this](https://stackoverflow.com/questions/6186980/determine-if-a-byte-is-a-pdf-file)) length 16 to show 8 bytes because of possible BOM. – Luuk Aug 22 '20 at 12:28
  • Hi @Luuk, here is the data when I tried to `SELECT LEFT(HEX(FileContent), 16)` , which the `FileContent` is the `LONGBLOB` data type: 504B030414000600 – Sky Aug 22 '20 at 12:39
  • I would expect `504446` to be in that string, so i think your PDF is not stored correctly, and that will make reading it hard... (or you accidently selected a document that is not a PDF) – Luuk Aug 22 '20 at 12:43
  • Hi @Luuk, sorry just now I upload the one that is not PDF, after I upload the PDF and I select the statement in MySQL, here is the data: 255044462D312E34 – Sky Aug 22 '20 at 12:55
  • Ok, the conclusion is that the PDF seems to be correctly stored in MySQL, because the first bytes show '%PDF', or in hex `26504446`. – Luuk Aug 22 '20 at 12:57
  • Hi @Luuk, yes, any solutions to it then? the PDF is stored correctly, however when I tried to download, the content is not readable, it can open, only that it is not readable, the content is like this when I download and open it (PDF): `%PDF1.4 %´μ¶ꞏ % 1 0 obj << /Dests 2 0` – Sky Aug 22 '20 at 13:00
  • I do not know what `RetrieveFileContentFromMySQLDB()` is, but what happens when you replace `return File(PDFBytes, "application/pdf", "File.pdf");` by: `return File(PDF, "application/pdf", "File.pdf");` – Luuk Aug 22 '20 at 13:03
  • Hi @Luuk, the `RetrieveFileContentFromMySQLDB()` is just read the `FileContent` column from the table which that column is `LONGBLOB` data type, I am using `Dapper` to auto bind the data from DB to C#, and the `FileContent` in C# is `byte[]` , also I cannot replace the `PDFBytes` to `PDF` as `File method in return FIle(` is expecting `byte[]`, while `PDF` or `PDFDoc` is not `byte[]` – Sky Aug 22 '20 at 13:06
  • oops, i meant replacing it with FileContent to: `return File(FileContent, "application/pdf", "File.pdf");`. Because FileContent should already contain the PDF, and should not need any change. – Luuk Aug 22 '20 at 13:11
  • The same as you are doing for Word, excecpt change `ContentType`, and `Content-Disposition`. – Luuk Aug 22 '20 at 13:14
  • Hi @Luuk, it works fine now after I changed it to what you have suggested. Thank you very much. However for the Word, what do you mean by change `ContentType` and `Content-Disposition`? – Sky Aug 22 '20 at 13:18
  • I meant do say change `DownloadPDF` to whatever you have in `DownloadWord`, and then change those two items in `DownloadPDF`. – Luuk Aug 22 '20 at 13:34
  • Hi @Luuk, sorry, I still don't get it, could you show me? Thank you very much – Sky Aug 22 '20 at 14:51

1 Answers1

0

I think you can change DownloadPDF() to :

public ActionResult DownloadPDF()
{
    byte[] FileContent = RetrieveFileContentFromMySQLDB();

    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("Content-Disposition", $"attachment;filename=File.pdf");
    Response.Charset = string.Empty;
    Response.ContentType = "application/pdf";
    Response.Output.Write(Encoding.Default.GetString(FileContent, 0, FileContent.Length));
    Response.Flush();
    Response.End();
    break;
}

Above is (almost) the same as DownloadWord(). The differences are the headers "Content-Disposition" and "Content-Type".

Luuk
  • 12,245
  • 5
  • 22
  • 33
  • Hi @Luuk, I have tried above solution for `DownloadPDF()`, however it didn't work as expected (the file is being downloaded, however it is only show white page even though I upload the file (PDF) which have content and not white page). Also there is another problem now: - When I upload the file with .doc or .docx and download the file as PDF, it is being downloaded, but it cannot be opened (the file is corrupted), same goes when I download the file as Word, it is being downloaded, but the content is just like all hex characters. For more info, please refer to above question I have edited – Sky Aug 23 '20 at 07:39
  • Just storing a PDF-file, and then download it 'as Word' will not convert a document. Also storing a Word-file, and then download it 'as PDF' will not convert it! – Luuk Aug 23 '20 at 08:25
  • Hi @Luuk, thank you very much, do you know any of the conversion way to do it? – Sky Aug 23 '20 at 08:33
  • There are many different tools to convert a Word document to PDF. From PDF to Word is harder, because some PDF documents only contain images, which are harder to convert to Word – Luuk Aug 23 '20 at 08:41
  • Hi @Luuk, okay got it, I will do the workaround, stored the File Extension into DB, and once user wants to download it to the other (Let;s say: Word extension is stored, and user click download as PDF), then I will do the conversion from Word to HTML, and then convert it back to PDF and vice versa. Do this will do the trick? – Sky Aug 23 '20 at 08:46