使用ASP.NET从Microsoft Dynamics Nav检索二进制/ Blob文件

时间:2014-11-11 14:52:14

标签: asp.net sql-server linq-to-sql navision

我正在使用具有文件附件表的MS Dynamics Nav数据库。这些文件存储在MS SQL中。我能够使用我构建的自定义asp.net应用程序将文件拉到我的桌面,但是当我打开文件时,它们已损坏。这些是PDF文件,位于数据库的“图像”文件类型列中,我试图下载超过20个文件。所有这些都有所不同,似乎下载成功 我怀疑这些是PDF文件的原因是因为二进制列旁边的列给出了PDF格式的文件名。我下载到不同的图像格式后,我也尝试重命名该文件,但当我尝试打开它时没有任何运气。这不是我从MS SQL数据库中检索二进制文件的第一个项目。如果有人在以前从Nav数据库中获取文件,请帮助我。我在下面的示例代码中使用LINQ to SQL检索文件,当我在浏览器中给它一个特定的ID时。如果您知道二进制文件本身中的任何压缩或加密以及如何成功获取文件以进行读取,请通知我。感谢

 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 个答案:

答案 0 :(得分:0)

好。我想到了。我在博客上看到4个字节是摆脱它的“神奇数字”。因此,您所要做的就是从BLOB字节数组中删除4个字节,然后使用DeflateStream对其进行解压缩。我在下面发布的示例代码是一个示例,它接收一个字节数组并使用LINQ-to-SQL跳过前4个,并返回第二个函数的字节和字符串文件名。它还传入一个queryid字符串参数。我确信为了提高效率,代码可以进行更多改进。对于那些有麻烦的人,请试一试。

    //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;
    }