Skip to content

Accessing Compressed Blobs from outside NAV (NAV2013)

January 17, 2013

21.01.14 – This Solution was not completly working, here is the new solutions, tested on NAV2013 R2 : https://devch.wordpress.com/2014/01/21/accessing-compressed-blobs-from-outside-nav-nav2013-revisited/

 

Just a short hint for anyone interested in accessing BLOB Fields in NAV. In the new Version, the BLOB compression is now longer a proprietary format, NAV now uses the .net deflate Class to compress the binary objects. (In a previous blogpost (https://devch.wordpress.com/2012/01/12/read-content-of-nav-notesblobs-from-sql/) I stated the need for disabling the compression on BLOB fields to access them from outside NAV)

Therefore you can no easily use the DeflateStream Class to decompress the content and access it.

So to decompress the content, the method would look something like this:

    public static long Decompress(Stream inp, Stream outp)
    {
    	byte[]  buf = new byte[BUF_SIZE];
    	long    nBytes = 0;

    	// Decompress the contents of the input file
    	using (inp = new DeflateStream(inp, CompressionMode.Decompress))
    	{
    		int len;
    		while ((len = inp.Read(buf, 0, buf.Length)) > 0)
    		{
    			// Write the data block to the decompressed output stream
    			outp.Write(buf, 0, len);
    			nBytes += len;
    		}
    	}
    	// Done
    	return nBytes;
    }

From → C# .NET, Dynamics NAV

11 Comments
  1. Lukas Kohler permalink

    hm, not working for me. I dont think its always DEFLATE compressed.

  2. Hi Lukas, i think at the time i checked this, NAV2013 was still in beta, maybe they changed something. Unfortunately for know i don’t have time to check it.

  3. When trying this on the [Object Metadata] table [Metadata] field, I get the error “Unknown block type. Stream might be corrupted” while trying to Decompress the binary field data using DeflateStream. I’m on NAV 2013 but maybe the NAV Object Metadata uses a different compression algorithm or some other custom binary format for these fields?

    • Yes, I think it’s another format then. Maybe you could find out what’s going on by reflecting the binaries of the service tier.

      Edit: I just had a look at the binaries myself, and there is no other behaviour then for normal BLOB fields. Could it be that there is no compression for the object metadata at all?
      You can investigate the method by yourself by using ILSpy (or a similar application):

      // Microsoft.Dynamics.Nav.Runtime.NavSqlCommand
      internal int GetBlobDataFromreader(NCLMetaField field, int resultIndex, NavBLOB navBlob)
      {
      int num = this.Reader.IsDBNull(resultIndex) ? 0 : ((int)this.Reader.GetBytes(resultIndex, 0L, null, 0, 0));
      if (num > 0)
      {
      using (Stream stream = new BlobReaderStream(this.Reader, resultIndex, num))
      {
      using (Stream newStream = navBlob.GetNewStream())
      {
      if (field.FieldIsCompressed)
      {
      byte[] array = new byte[4];
      long num2 = (long)stream.Read(array, 0, 4);
      if (num2 < 4L || !NavBLOB.BlobMagicOk(array))
      {
      this.CloseReader(false, true);
      return 22926086;
      }
      using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
      {
      deflateStream.CopyTo(newStream);
      goto IL_A0;
      }
      }
      stream.CopyTo(newStream);
      IL_A0:;
      }
      }
      return 0;
      }
      return 0;
      }

  4. Here is the new (working) solution: https://devch.wordpress.com/2014/01/21/accessing-compressed-blobs-from-outside-nav-nav2013-revisited/

    Please let me know if it’s working for you.

  5. kayess permalink

    Devch, can you do it with Nav2009 R2 using NAVRuntime?

    • Well when you are in NAV Runtime then you already have access to any blob fields content by using standard nav code. What exactly do you want to do and what does not work for you?

      • kayess permalink

        Actually I want to read object table out of navision and export them as text by using .net code. I am dealing with 20 nav databases with same code in all of them.

        • The Problem is you cannot design the object table, therefore you cannot set the compressed property to false, which is needed in databases before 2013, because the compression used before that is no standard compression and I don’t know of any way to read the content in this situation.

  6. kayess permalink

    can we do the same with object table? i tried your code, it works with object metadata table in nav 2015 but i get garbage / empty strings when i tried to blob reference field from object table.

Trackbacks & Pingbacks

  1. Accessing Compressed Blobs from outside NAV (NAV2013) (Revisited) | deV.ch - man vs. code

Leave a comment