簡體   English   中英

如何設置附件名稱以在Outlook中正確顯示

[英]How Set Attachment Name to Show Properly in Outlook

我正在使用BizTalk 2016 SMTP發送端口創建一個帶有MIME附件的電子郵件。 但是,我認為任何人都可以從任何其他語言中分享有關Outlook和MIME的奇怪之處的任何知識可能會幫助我解決下面的問題。

在Outlook中,附件顯示為body.txt,但是當我單擊“文件保存”時,它會顯示我在創建它時使用的名稱(這是用戶想要查看的名稱)。

我所指的是左側,在5k上方的“body.txt”和下面屏幕截圖中附件圖標的右側:

在此輸入圖像描述

在BizTalk C#Pipeline組件中,使用以下代碼設置該附件,我們在BizTalk消息上設置Context屬性。 我也嘗試過設置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)中顯示所需的名稱。

到目前為止,我已經開始使用帶有動態發送端口的業務流程。 它仍然有點工作,但它完成了庫存組件的工作。 以下描述基於BizTalk 2013R2中包含的庫存SMTP適配器。

注意:即使我的解決方案有效,感覺就像一個解決方法,我不應該做的事情,如果適配器只是稍微聰明一點。

首先,讓我們看一下示例電子郵件片段,它會導致某些客戶端出現問題:

------=_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" Content-Disposition: attachment; filename="CDM_Order - Copy.pdf"

硬設置MIME.FileName不僅可以工作,即使它最終會設置Content-Disposition ,它也永遠不會更新Content-Description 這是因為在靜態發送端口上,您已設置Attach only body part或者您在動態發送端口上指定了相應的數字值1

但是,它將與MessagePartsAttachments類型的Attach all parts2值一起使用。 這涉及在業務流程中制作多部分消息。 這將有兩個部分;

  • 第一個是BodyPart ,現在這個將包含您的消息文本而不是您的附件。 確保在Message Type將此指定為Message Body Part
  • 第二部分將是您的實際附件,根據您的附件類型指定此類型。 我在這個例子中命名了這個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;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM