BizTalk SMTP 发送带附件的邮件(无编排,自定义发送管道组件)

BizTalk SMTP send mail with attachments (no orchestration, custom send pipeline component)

我希望有人能帮我解决这个问题,因为当我将 JSON 测试文件放入我的 rcv 文件夹时,唯一的结果是在 BizTalk 控制台(在 'Running instances' 中),消息仅声明 'Queued (Awaiting processing)'。我不确定我的问题出在代码的什么地方。

我应该收到一个 JSON,其中将包含一些信息和可能的多个附件(Base64 格式),然后将邮件发送出去(附件格式正确,即 PDF、txt、xls)到某个电子邮件地址。要求之一是不使用编排。但是我被困住了,不知道自己在做什么了。这个问题与其他问题的不同之处在于我的解决方案中没有编排。一切都将在自定义发送管道组件中处理。 发送管道(在编码阶段)确实包含我的自定义组件以及 MIME/SMIME 编码器。我正在使用 SMTP 适配器。

我已经使用向导创建了自定义管道组件,我的初始计划如下所示:

  1. 接收文件(JSON格式。它将被转换为XML以供进一步处理)。这一切都将在我的 rcv-pipeline 中处理,这一步对我来说已经有效了。
  2. 从 XML 中选择发送电子邮件所需的所有必要变量。这些变量是我想在电子邮件文本中显示的变量。不确定如何更好地解释它。
  3. 挑选出所有base64格式的附件,遍历它们,转换为'regular files'然后将它们附加到邮件中(正确的文件名、扩展名等)

XML 如下所示:


ArchiveobjectsListErrands
  - ArchiveobjectErrand 
      * UUID (Here are the variables I need to show in the E-mail. The plain text, so to say)
    - ArchiveobjectListPaper
      - Attachments
        * Name
        * Extension
        * Size
        * Base64String (Base64 string which will be needed to be fetched (in GetAttachments) and then processed in (ProcessAttachments))

我的代码如下:

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            // 1) Read file with XPathNavigator (https://docs.microsoft.com/en-us/dotnet/standard/data/xml/extract-xml-data-using-xpathnavigator)
            XPathNavigator nav = ReadXmlFromMsgBox(pInMsg);

            var outMsg = pContext.GetMessageFactory().CreateMessage();
            outMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context);  

            // 2) Pick out the necessary vars that the registrator requires
            GetRegistratorProperties(nav, pContext, outMsg);

            // 3) Read attachments
            var attachments = GetAttachments(pInMsg, nav);

            // 4) Processa attachments
            ProcessAttachments(pContext, outMsg, attachments);

            // 5) Send message along for further processing in the send pipeline
            return outMsg;
        }

        private void GetRegistratorProperties(XPathNavigator _nav, IPipelineContext _pContext, IBaseMessage _msg)
        {
            var bodyPart = _pContext.GetMessageFactory().CreateMessagePart();             
                     
            bodyPart.ContentType = "text/application";  

            bodyPart.PartProperties.Write("EmailBodyText", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", "EmailBodyText.");
            bodyPart.PartProperties.Write("Subject", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", "Registratorsubject - Create errand");

            _msg.AddPart("Body", bodyPart, true); // True for body but false for attachments

        }

        private void ProcessAttachments(IPipelineContext _pContext, IBaseMessage _msg, IList<Attachment> _attachments)
        {
            
            var msgPart = _pContext.GetMessageFactory().CreateMessagePart();
            //outMsg.Context = PipelineUtil.CloneMessageContext(_msg.Context);  

            int i = 0;            
            foreach (var item in _attachments)
            {    
                msgPart.PartProperties.Write("FileName", "http://schemas.microsoft.com/BizTalk/2003/mime-properties", item.filnamn+item.extension);
                msgPart.PartProperties.Write("ContentDescription", "http://schemas.microsoft.com/BizTalk/2003/mime-properties", item.contentType);
                msgPart.Data = new MemoryStream(BytesFromBase64String(item.base64));
                //bodyPart.Charset = "utf-8";
                msgPart.ContentType = item.contentType;  

                //_pInMsg.AddPart("Attachment part " + i.ToString(), bodyPart, false); 
                _msg.AddPart("Attachment part " + i.ToString(), msgPart, false); 
                i++;
            }
        }

        private IList<Attachment> GetAttachments(IBaseMessage pInMsg, XPathNavigator _nav)
        {
            XPathNodeIterator iterator =  _nav.Select("Path to attachments in xml");
            IList<Attachment> myList = new List<Attachment>();                        
            

            while (iterator.MoveNext())
            {
                XPathNavigator node = iterator.Current;

                Attachment atttachments = new Attachment();              

                atttachments.filenamne = node.SelectSingleNode("Name").Value;
                atttachments.extension = node.SelectSingleNode("Extension").Value;
                atttachments.contentType = node.SelectSingleNode("Mimetype").Value;
                atttachments.base64 = node.SelectSingleNode("Base64String").Value;

                myList.Add(atttachments);
            }

            return myList;
        }

        private XPathNavigator ReadXmlFromMsgBox(IBaseMessage pInMsg)
        {
            // Using XPathNavigator to avoid creating a XMLDoc in memory
            Stream originalMessage = pInMsg.BodyPart.GetOriginalDataStream();

            XPathNavigator _navigator = new XPathDocument(originalMessage).CreateNavigator();
            return _navigator;
        }        

        [Serializable]
        private class FileStreamFactory : IStreamFactory
        {
            byte[] _data;

            public FileStreamFactory(byte[] data)
            {
                _data = data;
            }

            public Stream CreateStream()
            {
                return new MemoryStream(_data);
            }
        }

        private static byte[] BytesFromBase64String(string msg)
        {
            return Convert.FromBase64String(msg);
        }
        #endregion
        }

如果认为有必要,我可以展示 XML 的一些示例文件。由于简洁,我避免了它,也因为它非常大。

如果有人能帮助解决代码应该如何实现所需的问题,一封包含一些文本和附件的邮件,并根据文件名和扩展名正确命名,我将不胜感激。

正文和附件只是 MIME 编码电子邮件中的不同部分,通常纯文本是第一个。

如果它的状态为 'Queued (Awaiting processing)',则听起来像是

  • 期望处理它的主机实例不在 运行 状态。修复:启动主机实例。
  • 发送端口未处于已启动状态。修复:将发送端口设置为 Started
  • 或者发送端口设置了服务window。修复:禁用服务 window.