Stream was not writable error in custom pipeline component

Hi all,

We are writing a custom pipeline component to check if the file size is empty or 0kb. If yes, then we are sending a string called "EmptyFile". But we are receiving an error saying "Stream was not writable". Can anyone suggest what changes we can do in the below code.

IBaseMessagePart bodyPart = inmsg.BodyPart;
            Stream originalStream = inmsg.BodyPart.GetOriginalDataStream();      
            if (originalStream.Length == 0)
           {
               System.IO.StreamWriter sw = new StreamWriter(originalStream);
               sw.Write("EmptyFile");
               inmsg.BodyPart.Data = originalStream;
              sw.Close();
              return inmsg;

Thanks in advance,

Veena

September 4th, 2015 1:16am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 1:51am

Hi Veena,

The original stream you are getting from the BodyPart is a ReadOnly stream. You need to create a new Stream(either new or a copy of the received) and assign it to the BodyPart Data property.

For example:

MemoryStream targetStream = new MemoryStream();
System.IO.StreamWriter sw = new StreamWriter(targetStream);
sw.Write("EmptyFile");
inmsg.BodyPart.Data = targetStream;
sw.Close();
return inmsg;

Regards.

September 4th, 2015 2:38am

hi Vikas,

We tried and its working. But we have some other problem now. After it passes the null through this custom pipeline component, the flat file disassembler fails. We may have to extend the disassembler component functionality as well in this. Anyways thank you for the help.

Thanks and Regards,

Veena

Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 4:20am

Hi Veena,

The above component gives data if it has data to the next component, else it gives data with the "Empty File" - not returning null.

Can you tell me the cases what you are trying to achieve or the scenarios? so that we can help.

The next FF Disassembler component expects data to disassemble, it fails for sure if you send null, if you have your own custom FF Disassembler then you can handle null data and suppress their only processing of the message.

Thanks, SMSVikasK


  • Edited by SMSVikasK 21 hours 54 minutes ago
September 4th, 2015 5:06am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 5:46 AM
  • Proposed as answer by SMSVikasK 23 hours 38 minutes ago
  • Unproposed as answer by SMSVikasK 22 hours 8 minutes ago
Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 5:46am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 5:46 AM
  • Proposed as answer by SMSVikasK Friday, September 04, 2015 7:29 AM
  • Unproposed as answer by SMSVikasK Friday, September 04, 2015 8:59 AM
September 4th, 2015 5:46am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 5:46 AM
  • Proposed as answer by SMSVikasK Friday, September 04, 2015 7:29 AM
  • Unproposed as answer by SMSVikasK Friday, September 04, 2015 8:59 AM
  • Proposed as answer by SMSVikasK 18 hours 25 minutes ago
Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 5:46am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 5:46 AM
  • Proposed as answer by SMSVikasK Friday, September 04, 2015 7:29 AM
  • Unproposed as answer by SMSVikasK Friday, September 04, 2015 8:59 AM
  • Proposed as answer by SMSVikasK Monday, September 07, 2015 12:36 PM
September 4th, 2015 5:46am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 5:46 AM
  • Proposed as answer by SMSVikasK Friday, September 04, 2015 7:29 AM
  • Unproposed as answer by SMSVikasK Friday, September 04, 2015 8:59 AM
  • Proposed as answer by SMSVikasK Monday, September 07, 2015 12:36 PM
Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 5:46am

Hi Veena,

To know more,

if the file is empty or zero length, in the same file you need to write "Empty File" and send the file else send same data as is ?

if so please find the below code to use in decode or any other stage.

#region IComponent members
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            try
            {
                StreamReader streamReader = new StreamReader(pInMsg.BodyPart.GetOriginalDataStream());
                StringBuilder sb = new StringBuilder();
                if (streamReader.BaseStream.Length == 0)
                {
                    sb.Append("Empty File");
                }
                else
                {
                    sb.Append(streamReader.ReadToEnd());
                }
                streamReader.Close();
                byte[] bytesString = Encoding.UTF8.GetBytes(sb.ToString());
                MemoryStream OutmemoryStream = new MemoryStream();
                OutmemoryStream.Write(bytesString, 0, bytesString.Length);
                OutmemoryStream.Seek(0, SeekOrigin.Begin);
                pInMsg.BodyPart.Data = OutmemoryStream;
                pContext.ResourceTracker.AddResource(OutmemoryStream);
                return pInMsg;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

Let us know if you face any issues.

Thanks, SMSVikasK


September 4th, 2015 5:46am

Pattern wise, I would not modify the stream.

Instead, set a context property the flag's the empty message as such.

Then, instead of extending the Flat File Disassembler, just create a Empty File Disassembler and put it first in the Disassemble Stage.  Since only one disassembler will fire, any following Flat File Disassemblers will be skipped.

Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 6:34am

Hi Veena,

The above component gives data if it has data to the next component, else it gives data with the "Empty File" - not returning null.

Can you tell me the cases what you are trying to achieve or the scenarios? so that we can help.

The next FF Disassembler component expects data to disassemble, it fails for sure if you send null, if you have your own custom FF Disassembler then you can handle null data and suppress their only processing of the message.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 9:13 AM
September 4th, 2015 9:04am

Hi Veena,

The above component gives data if it has data to the next component, else it gives data with the "Empty File" - not returning null.

Can you tell me the cases what you are trying to achieve or the scenarios? so that we can help.

The next FF Disassembler component expects data to disassemble, it fails for sure if you send null, if you have your own custom FF Disassembler then you can handle null data and suppress their only processing of the message.

Thanks, SMSVikasK


  • Edited by SMSVikasK Friday, September 04, 2015 9:13 AM
Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 9:04am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics