Пока у меня это работает с оркестровкой с динамическим портом отправки. Это все еще немного работы, но она справляется со стандартным компонентом. Следующее описание основано на стандартном SMTP-адаптере, включенном в BizTalk 2013R2.
Примечание: хотя мое решение работает, оно похоже на обходной путь, и мне не следовало бы делать это, если бы адаптер был немного умнее в этом.
Прежде всего, давайте рассмотрим пример кода электронной почты, который вызывает проблемы у некоторых клиентов:
------=_NextPart_000_0001_01D4502F.8A6A1500
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="utf-8"
See attached email.
------=_NextPart_000_0001_01D4502F.8A6A1500
Content-Type: application/pdf; name="CDM_Order - Copy.pdf"
Content-Disposition: attachment; filename="CDM_Order - Copy.pdf"
Content-Description: body
Content-Transfer-Encoding: base64
JVBERi0xLjQKJeLjz9MNCjUgMCBvYmoKPDwvRFsgMyAwIFIvWFlaIG51bGwgODQxLjg4OTc3IG51
bGwgXQo+PgplbmRvYmoKOCAwIG9iago8PC9EWyAzIDAgUi9YWVogbnVsbCAyOTAuMjM2NTcgbnVs
bCBdCj4+ (etc etc base64 your file)...
Обратите внимание на часть Content-Description: body
. По этой причине некоторые клиенты читают body.xml
или, в моем случае, body.pdf
, хотя часть Disposition выглядит отлично: Content-Disposition: attachment; filename="CDM_Order - Copy.pdf"
.
Жесткая установка MIME.FileName
не просто сработает, даже если она в конечном итоге установит Content-Disposition
правильно, она никогда не обновит Content-Description
. Это связано с тем, что либо для статического порта отправки вы установили Attach only body part
, либо вы указали соответствующее числовое значение 1
для динамического порта отправки.
Однако он будет работать со значением Attach all parts
или 2
для типа MessagePartsAttachments
. Это включает в себя создание сообщения, состоящего из нескольких частей, в вашей оркестровке. Он будет состоять из двух частей;
- Первый - это
BodyPart
, теперь он будет включать в себя текст сообщения, а не вложение. Убедитесь, что вы указали этот параметр как Message Body Part
в Message Type
.
- Вторая часть будет вашим фактическим вложением, укажите этот тип в соответствии с вашим типом вложения. В этом примере я назвал это
Attachment
.
Теперь вы можете подумать, что он также отправит BodyPart
как вложение, поскольку я сказал, что нам нужен Attach all parts
. Это правда, поэтому, чтобы исправить это, ваш BodyPart
должен быть определен как RawString
, это превращает строку в простой текст в части сообщения BizTalk. Для полноты картины я помещу класс C # внизу для справки.
Теперь, когда он определен как RawString
, адаптер SMTP поместит его как тело, а не как вложение. В качестве побочного эффекта адаптер SMTP больше не будет помещать часть Content-Description: body
во вложенную часть, а вместо этого будет помещать ее в фактическую часть тела. Выглядит это так:
------=_NextPart_000_0001_01D450E4.A7E9A5E0
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="utf-8"
Content-Description: body
See attached email.
------=_NextPart_000_0001_01D450E4.A7E9A5E0
Content-Type: application/pdf; name="ID_0_Nummer_0.pdf"
Content-Disposition: attachment; filename="ID_0_Nummer_0.pdf"
Content-Transfer-Encoding: base64
JVBERi0xLjQKJeLjz9MNCjUgMCBvYmoKPDwvRFsgMyAwIFIvWFlaIG51bGwgODQxLjg4OTc3IG51
bGwgXQo+PgplbmRvYmoKOCAwIG9iago8PC9EWyAzIDAgUi9YWVogbnVsbCAyOTAuMjM2NTcgbnVs
bCBdCj4+ (etc etc base64 your file)...
На самом деле ничем не отличается, кроме размещения Content-Description: body
части, именно то, что мы хотим. Теперь письмо подходит каждому клиенту.
Для правильной работы необходимо также установить наиболее важные свойства, помимо тех, о которых я уже упоминал:
Тип содержимого вашего тела:
MsgPdfOrder.BodyPart(Microsoft.XLANGs.BaseTypes.ContentType) = "text/plain";
Тип содержимого вашего вложения:
MsgPdfOrder.Attachment(Microsoft.XLANGs.BaseTypes.ContentType) = "application/pdf";
Имя файла вложения:
MsgPdfOrder.Attachment(MIME.FileName) = "CDM_Order - Copy.pdf"
Набор символов тела (если не задан, будет Unknown Error Description
):
MsgPdfOrder(SMTP.EmailBodyTextCharset) = "UTF-8";
Убедитесь, что вы не установили SMTP.EmailBodyText
, потому что у нас уже есть BodyPart
для этого.
RawString, используйте его в оркестровке MsgPdfOrder.BodyPart = new Yournamespace.Components.RawString("See attached email.");
:
using System.Runtime.Serialization;
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using Microsoft.XLANGs.BaseTypes;
namespace Yournamespace.Components
{
public abstract class BaseFormatter : IFormatter
{
public virtual SerializationBinder Binder
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public virtual StreamingContext Context
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public virtual ISurrogateSelector SurrogateSelector
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public abstract void Serialize(Stream stm, object obj);
public abstract object Deserialize(Stream stm);
}
public class RawStringFormatter : BaseFormatter
{
public override void Serialize(Stream s, object o)
{
RawString rs = (RawString)o;
byte[] ba = rs.ToByteArray();
s.Write(ba, 0, ba.Length);
}
public override object Deserialize(Stream stm)
{
StreamReader sr = new StreamReader(stm, true);
string s = sr.ReadToEnd();
return new RawString(s);
}
}
[CustomFormatter(typeof(RawStringFormatter))]
[Serializable]
public class RawString
{
[XmlIgnore]
string _val;
public RawString(string s)
{
if (null == s)
throw new ArgumentNullException();
_val = s;
}
public RawString()
{
}
public byte[] ToByteArray()
{
return Encoding.UTF8.GetBytes(_val);
}
public override string ToString()
{
return _val;
}
}
}
person
r3verse
schedule
20.09.2018