Как правильно установить имя вложения в Outlook
Я создаю электронное письмо с вложением MIME из порта отправки SMTP BizTalk 2016. Однако я думаю, что любые знания, которые кто-либо может поделиться с любого другого языка о странностях Outlook и MIME, могут помочь мне решить проблему ниже.
в Outlook вложение отображается как тело.txt, но когда я нажимаю "сохранить файл", он показывает имя, которое я использовал при его создании (и это то, что пользователь хочет видеть).
то, что я имею в виду, - это левая сторона, где она говорит "тело.txt " над 5k и справа от значка вложения на снимке экрана ниже:
в компоненте конвейера BizTalk C# это вложение было установлено со следующим кодом, где мы задаем свойства контекста в сообщении BizTalk. Я также попытался установить ContentHeader и ContentID.
strFilename = "MyFileName_693.txt"; // Just for example.
pInMsg.BodyPart.PartProperties.Write(
"FileName",
"http://schemas.microsoft.com/BizTalk/2003/mime-properties",
strFilename);
когда я отправил электронное письмо в Gmail, вложение было показано с собственным именем. Так что мой вопрос особенный. чтобы он появился с нужным именем в Outlook (2016).
1 ответов
до сих пор у меня это работает с оркестровкой с динамическим портом отправки. Это все еще немного работы, но она выполняет работу с компонентом запаса. Следующее описание основано на наличии 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
, хотя часть расположения выглядит великолепно: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;
}
}
}