在发送电子邮件时设置回复地址 EWS

3

运行Exchange 2013

我正在使用C#服务中的EWS发送电子邮件,该服务使用服务账户发送邮件。

我希望电子邮件具有与发件人账户不同的回复地址,即分发列表地址。

我该如何做?EmailMessage.ReplyTo字段是只读的。

代码:

ExchangeService service = new ExchangeService();
service.Credentials = EWScredentials;
service.Url = new Uri(string.Format("https://{0}/EWS/Exchange.asmx", ExchangePath));

EmailMessage message = new EmailMessage(service);
message.ToRecipients.AddRange(receipients);

//This didn't work
message.ReplyTo.Clear();
message.ReplyTo.Add(replyToAddress);

message.Subject = subject;
message.Body = html;
message.SendAndSaveCopy();

这是与之相关的另一个线程,尽管我没有使用PowerShell:如何使用EWS Managed API设置消息的回复地址?

5个回答

4
您可以使用PidTagReplyRecipientEntries扩展属性https://msdn.microsoft.com/zh-cn/library/office/cc815710.aspx来实现此功能。
        EmailMessage DifferentReplyTo = new EmailMessage(service);
        DifferentReplyTo.Subject = "test";
        DifferentReplyTo.ToRecipients.Add("destination@domain.com");
        DifferentReplyTo.Body = new MessageBody("test");           
        ExtendedPropertyDefinition PidTagReplyRecipientEntries = new ExtendedPropertyDefinition(0x004F, MapiPropertyType.Binary);
        ExtendedPropertyDefinition PidTagReplyRecipientNames = new ExtendedPropertyDefinition(0x0050, MapiPropertyType.String);
        DifferentReplyTo.SetExtendedProperty(PidTagReplyRecipientEntries, ConvertHexStringToByteArray(GenerateFlatList("departmentdg@domain.com", "jc")));
        DifferentReplyTo.SetExtendedProperty(PidTagReplyRecipientNames, "jc");
        DifferentReplyTo.SendAndSaveCopy();

    internal static String GenerateFlatList(String SMTPAddress, String DisplayName)
    {
        String abCount = "01000000";
        String AddressId = GenerateOneOff(SMTPAddress, DisplayName);
        return abCount + BitConverter.ToString(INT2LE((AddressId.Length / 2) + 4)).Replace("-", "") + BitConverter.ToString(INT2LE(AddressId.Length / 2)).Replace("-", "") + AddressId;
    }

    internal static String GenerateOneOff(String SMTPAddress,String DisplayName)
    {
        String Flags = "00000000";
        String ProviderUid = "812B1FA4BEA310199D6E00DD010F5402";
        String Version = "0000";
        String xFlags = "0190";
        String DisplayNameHex = BitConverter.ToString(UnicodeEncoding.Unicode.GetBytes(DisplayName + "\0")).Replace("-","");
        String SMTPAddressHex = BitConverter.ToString(UnicodeEncoding.Unicode.GetBytes(SMTPAddress + "\0")).Replace("-", "");
        String AddressType = BitConverter.ToString(UnicodeEncoding.Unicode.GetBytes("SMTP" + "\0")).Replace("-", "");
        return Flags + ProviderUid + Version + xFlags + DisplayNameHex + AddressType + SMTPAddressHex;
    }
    internal static byte[] INT2LE(int data)
    {
        byte[] b = new byte[4];
        b[0] = (byte)data;
        b[1] = (byte)(((uint)data >> 8) & 0xFF);
        b[2] = (byte)(((uint)data >> 16) & 0xFF);
        b[3] = (byte)(((uint)data >> 24) & 0xFF);
        return b;
    }
    internal static byte[] ConvertHexStringToByteArray(string hexString)
    {
        if (hexString.Length % 2 != 0)
        {
            throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
        }

        byte[] HexAsBytes = new byte[hexString.Length / 2];
        for (int index = 0; index < HexAsBytes.Length; index++)
        {
            string byteValue = hexString.Substring(index * 2, 2);
            HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
        }

        return HexAsBytes;
    }

你好,Glen!


1
所以,有一个问题:你的代码中没有ConvertHexStringToByteArray方法。也许你是指像这样的东西:https://dev59.com/FXRC5IYBdhLWcg3wXPwC? - Aaron
1
使用那个问题中的代码添加一个ConvertHexStringToByteArray方法并尝试您的代码似乎没有改变答复地址,至少在我们员工的Outlook客户端上没有改变。但它确实编译并运行。 - Aaron
1
我已经添加了我使用的转换方法,如果您检查传输标头,您会看到什么?对我来说测试没问题,您可以尝试在Outlook中执行相同的操作,然后使用Mapi编辑器比较Outlook和您的代码之间的两个值。 - Glen Scales
1
好的,我已经编译并执行了代码,并正在查看我从Exchange收到的电子邮件,使用MS的MAPI编辑器。我以前没有使用过这个编辑器,所以还在摸索中,它列出了属性和值。属性“PR_REPLY_RECIPIENT_ENTRIES”未出现在列表中。我还从链接的文档中看到,“如果设置了此属性或PR_REPLY_RECIPIENT_NAMES属性,则必须同时设置另一个属性。”无论如何,它似乎还没有起作用。顺便说一下,我们正在运行Exchange 2013,我正在运行Outlook 2016。 - Aaron
我已将PidTagReplyRecipientNames添加到代码示例中,只是一个字符串属性。您需要查看“已发送项”文件夹中消息的副本才能查看这些属性,因为它们是信封属性,不会出现在接收到的消息上。为此,您应该仅查看传输头以查看是否可以看到“回复地址”标头。我正在使用Office365(因此是Exchange 2016)和Outlook 2013,但与Exchange 2013应该相同。 - Glen Scales
非常好!不确定哪一步修复了我的问题!我现在可以在编辑器中看到该属性,并且在Outlook中它也能正确显示地址。谢谢! - Aaron

0

我相信这个问题是因为已经有6年了,而且库已经更新了。

ReplyTo 属性是一个只读的 EmailAddressCollection,可以清除并添加。

var emailSend = new EmailMessage(service)
emailSend.ToRecipients.Add("recipient@example.com");

// change the reply-to
if(email.FromAddress.ToLower() != "noreply@example.com"){
    emailSend.ReplyTo.Clear();
    emailSend.ReplyTo.Add(new EmailAddress() { Address = "replyto@example.com" });
}
                                
emailSend.Save();
emailSend.Send(); 

0

这对我有用:

EmailAddressCollection emailAddressCollection = new EmailAddressCollection();
emailAddressCollection.add(new EmailAddress("ReplayToEmail@gmail.com"));
emailMessage.getPropertyBag().setObjectFromPropertyDefinition(EmailMessageSchema.ReplyTo, emailAddressCollection);

EmailAddressCollection的构造函数是内部的。 - Yan F.

0

有一个更简单的解决方案:使用ResponseMessage

ResponseMessage responseMessage = originalEmail.createReply(isReplyAll);
responseMessage.getToRecipients().addEmailRange(...email address...);
responseMessage.sendAndSaveCopy();

0

我通过在EmailMessage replyMessage对象上加载ToRecipientsCcRecipients属性来解决了这个问题。

C#代码大致如下:

// somehow get a hold of an ExchangeService object
var message = service.Bind(service, mail.Id);
var replyMessage = message.CreateReply(replyToAll: true);

replyMessage.Load(new PropertySet() { EmailMessageSchema.ToRecipients, EmailMessageSchema.CcRecipients });

replyMessage.ToRecipients.Add("some_email@email.com");
replyMessage.CcRecipients.Add("some_email_cc@email.com");

replyMessage.Send();

当然,如果您不打算使用Cc进行工作,那么您就不必加载它。这样可以让您添加新的地址,或清除收件人并添加任何您想要的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接