retrieving Binary/Blob files from Microsoft Dynamics Nav with ASP.NET

2.3k views Asked by At

I am working with a MS Dynamics Nav Database that have a file attachment tables. The files are stored in MS SQL. I am able to pull the files to my desktop with a custom asp.net application that I have built, but when I open the files, they are corrupted. These are PDFs files that are located in the "image" file type column of the database and I have tried to download over 20 files. All of them varies in size and seem to download successfully.
The reason why I suspect these are PDFs files is because the column right next to the binary columns give me the name of the file as in PDF format. I have also tried to renaming the file after I download to different image formats but without any luck when I tried to open it. This is not my first project to retrieve binary files, from MS SQL database. If anyone work on getting files off the Nav database before, please help me. The sample code below I wrote to retrieve files using LINQ to SQL when I give it a specific ID in the browser. Please advice me if you know any sort of compression or encryption in the binary files itself and how to grab the file successfully to read it. Thanks

 protected void getFileFromID(string queryid)
    {
        string Filename = string.Empty;


        byte[] bytes;

        try
        {
            DataClassesFilesDataContext dcontext = new DataClassesFilesDataContext();

            var myfile = (from file in dcontext.Comptroller_File_Attachments
                          where file.No_ == queryid
                          select file).First();

            if (myfile.Table_ID.ToString().Length > 0 && myfile.Attachment != null)
            {
                Filename = myfile.FileName.ToString();

                bytes = myfile.Attachment.ToArray();
                Response.Clear();                   
                Response.ContentType = "application/octet-stream";                 
                Response.AddHeader("Content-Disposition", "attachment; filename=" + Filename);
                Response.BinaryWrite(bytes);               
                Response.End();
            }

            else
            {
                Response.Write("no file exist");
            }
        }

        catch (Exception e)
        {
            Response.Write(e);

        }
    }
1

There are 1 answers

1
JonL On BEST ANSWER

Well. I figured it out. I read on a blog that 4 bytes was the "magic number" to get rid off. So all you have to do is get rid of 4 bytes from the BLOB bytes array and then decompress it with DeflateStream. The example code I post below is an example where it takes in a byte array and skip the first 4 using LINQ-to-SQL and return the byte and string filename for the 2nd function. It also pass in a queryid string parameter. I am sure the code can be improve more for efficiency purposes. For those who have trouble with this, just give this a try.

    //get bytes and remove first 4 bytes from bytes array
  protected Tuple<byte[], string> getBytesfromFile(string queryID)
  {

      byte[] MyFilebytes = null;
      string filename = string.Empty;

        try
        {
            DataClassesFilesDataContext dcontext = new DataClassesFilesDataContext();

            var myfile = (from file in dcontext.Comptroller_File_Attachments
                          where file.No_ == queryID
                          select file).First();

            if (myfile.Table_ID.ToString().Length > 0 && myfile.Attachment != null)
            {

                MyFilebytes = myfile.Attachment.ToArray().Skip(4).ToArray();
               filename = myfile.FileName.ToString();
            }

            else
                Response.Write("no byte to return");

        }
      catch 
     {
         Response.Write("no byte");
     }

        return Tuple.Create(MyFilebytes, filename);
  }

    //after getting the remaining bytes (after removing 4 first byte) deflate the byte and then store it in a memory steam and get the result back.
  protected void getFile()
  {
      try
      {
          string Filename = string.Empty;
          byte[] myfile = getBytesfromFile(getQueryID()).Item1;

          byte[] result;

          using (Stream input = new DeflateStream(new MemoryStream(myfile),
                                        CompressionMode.Decompress))
          {
              using (MemoryStream output = new MemoryStream())
              {
                  input.CopyTo(output);
                  result = output.ToArray();
              }
          }

          Filename = getBytesfromFile(getQueryID()).Item2;


          Response.Clear();
          Response.ContentType = "application/octet-stream";
          Response.AddHeader("Content-Disposition", "attachment; filename=" + Filename);
          Response.BinaryWrite(result);
          Response.End();
      }

      catch (Exception e)
      {
          Response.Write(e);
      }

  }
    //pass in file id
    protected string getQueryID()
    {

        QueryID.QueryStringID = Request.QueryString["fileid"];
        return QueryID.QueryStringID;
    }