How to deal with non seekable stream

Bastien BRAILLY-VIGNAL
Category : BizTalk
31/10/2018

I recently faced a problem when dealing with stream in a custom BizTalk pipeline component.

Apparently, it sometimes happens the stream you are using is not seekable :

Error :  ForwardOnlyEventingReadStream does not support Seek()

non seekable stream error

To fix this issue, you just have to wrap the stream using the «SeekableReadOnlyStream ».


public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
    try
    {
        //Do something [...]
        Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
        if (originalStream != null)
        {
            if (!originalStream.CanSeek) // check if originalStream can seek
            {
                SeekableReadOnlyStream seekableStream = new SeekableReadOnlyStream(originalStream); // create a new seekable stream
                seekableStream.Position = 0;
                pInMsg.BodyPart.Data = seekableStream; // set new stream for the body part data of the input message
                pInMsg.BodyPart.Data.Position = 0;
                originalStream = pInMsg.BodyPart.Data; // replace originalStream with a new seekable stream wrapper
            }
            else
            {
                originalStream.Seek(0, SeekOrigin.Begin);
            }
        }
        //Do something [...]
    }
    catch (Exception e)
    {
        throw new Exception("Error : " + e.Message);
    }
    return pInMsg;
}

And it works fine !

If you are dealing with large data, then VirtualStream is probably the best option as it uses a disk file for data storage instead of memory (from the moment data size exceeds a configured value).

More information about the streaming support in BizTalk : https://mohamadhalabi.com/2013/12/29/biztalk-2013-streaming-support/.