BizTalk SMTP 发送带有附件的邮件(无编排,自定义发送管道组件)
Posted
技术标签:
【中文标题】BizTalk SMTP 发送带有附件的邮件(无编排,自定义发送管道组件)【英文标题】:BizTalk SMTP send mail with attachments (no orchestration, custom send pipeline component) 【发布时间】:2021-12-18 20:31:35 【问题描述】:我希望有人能帮我解决这个问题,因为当我将 JSON 测试文件放到我的 rcv 文件夹中时,唯一的结果是在 BizTalk 控制台中(在“正在运行的实例”中),消息仅显示“已排队(等待加工)'。我不确定我的问题出在代码中。
我应该收到一个 JSON,其中将包含一些信息和可能的多个附件(Base64 格式),然后将邮件(带有正确格式的附件,即 PDF、txt、xls)发送到某个电子邮件地址.要求之一是不使用编排。但我被困住了,不知道我在做什么了。这个问题与其他问题的不同之处在于我的解决方案中没有编排。一切都将在自定义发送管道组件中处理。 sendpipeline(在编码阶段)确实包含我的自定义组件以及 MIME/SMIME 编码器。我正在使用 SMTP 适配器。
我已经使用向导创建了自定义管道组件,我的初始计划如下:
-
接收文件(JSON 格式。它将被转换为 XML 以供进一步处理)。这一切都将在我的 rcv-pipeline 中得到解决,这一步已经对我有效。
从 XML 中挑选出所有必要的变量,以便在电子邮件中发送。这些变量是我想在电子邮件文本中显示的变量。不知道如何更好地解释它。
挑选出 base64 中的所有附件,遍历它们,转换为“常规文件”,然后将它们附加到邮件中(使用正确的文件名、扩展名等)
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 示例文件。由于简洁,也因为它很大,我避免了它。
如果有人能帮助了解代码应该如何实现所需的功能,我将不胜感激,邮件中包含正确命名的有关文件名和扩展名的一些文本和附件。
【问题讨论】:
1) 在一个问题中提出多个问题将使您的问题结束。 2)代码有效还是您有特定问题? 3) 正文和附件只是 MIME 编码电子邮件中的不同部分,通常是纯文本的第一个。 @Dijkgraaf,感谢您的澄清。我希望这篇编辑过的帖子能更清楚地说明问题所在。您说 MIME 编码的电子邮件实际上只有两个部分。那么我在 GetRegistratorProperties 方法中设置的值是否不正确?我正在使用 bodyPart.PartProperties.Write(...) 设置“纯文本属性”(据我所知),然后 _msg.AddPart("Body", bodyPart, true); // 正文为真,附件为假,将所有纯文本字段添加到电子邮件的纯文本段。但这也许是错误的做法? 如果它的状态为'Queued (Awaiting processing)',那么听起来像是期望处理的主机实例就是它,没有处于运行状态。检查发送端口所在的主机实例是否正在运行,并且发送端口处于已启动状态,并且您没有为其设置计划。 @Dijkgraaf,非常感谢您的回答。这让我更进一步。我仍然没有电子邮件出来,但我至少更近了一步。我真的不敢相信微软没有教程或如何实际做到这一点的东西......(PS由于某种原因我不能将你的答案设置为接受的答案。) 那是因为我将其发布为评论,而不是答案。我已将其发布为答案。 【参考方案1】:正文和附件只是 MIME 编码电子邮件中的不同部分,通常纯文本是第一个。
如果它的状态为“已排队(等待处理)”,那么听起来像
预期处理它的主机实例未处于运行状态。修复:启动主机实例。 发送端口未处于已启动状态。修复:将发送端口设置为已启动 或发送端口上设置了服务窗口。修复:禁用服务窗口。【讨论】:
以上是关于BizTalk SMTP 发送带有附件的邮件(无编排,自定义发送管道组件)的主要内容,如果未能解决你的问题,请参考以下文章
正文部分在 biztalk 动态 SMTP 发送端口中作为附件发送
通过 SMTP 发送带有附件、纯文本/文本和文本/html 的电子邮件