尝试使用Exchange Web Services Managed API针对 Exchange Server 2010 SP1 发送电子邮件时,将使用ErrorCode {{3}引发 ServiceException 当收件人的电子邮件地址(@的左侧)包含,在这种情况下,丹麦字母æøå。
这些字符是否仅在电子邮件地址的本地部分中被允许,或者我应该以某种方式对地址进行编码?
更新:以下是测试源代码和跟踪数据:
var service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.AutodiscoverUrl("my@email.com");
EmailMessage email = new EmailMessage(service);
email.Body = "Test";
email.Subject = "Test";
email.ToRecipients.Add("æøå@domain.com");
email.Send();
来自EWS的跟踪数据显示以下内容:
请求标题:
POST /EWS/Exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/14.03.0032.000
Accept-Encoding: gzip,deflate
请求:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010_SP1" />
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendOnly">
<m:Items>
<t:Message>
<t:Subject>Test</t:Subject>
<t:Body BodyType="HTML">Test</t:Body>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>æøå@domain.com</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
响应:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="14" MinorVersion="1" MajorBuildNumber="438" MinorBuildNumber="0" Version="Exchange2010_SP1" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Error">
<m:MessageText>One or more recipients are invalid.</m:MessageText>
<m:ResponseCode>ErrorInvalidRecipients</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
<m:Items />
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
最后,在Outlook中创建一个这样的地址的电子邮件会显示以下消息:
答案 0 :(得分:1)
根据处理Exchange收件人解析的这篇文章,您可能需要使用以下方法对这些字符进行编码:
字母数字字符,等号(=)和连字符( - )不 需要编码。其他字符使用以下编码语法: 正斜杠(/)由下划线(_)替换。其他US-ASCII 字符由加号(+)及其两位数字代替 ASCII值以十六进制写入。例如,空间 character的编码值为+20。
http://technet.microsoft.com/en-us/library/bb430743(v=exchg.141).aspx
所以你的“æøå@domain.com”的例子将成为“+ e6 +f8 + e5@domain.com”
修改强>
如果使用特殊字符,地址的“域”部分也需要使用不同的方法进行编码。
以下是我使用RFC 5321和RFC 3461规范对电子邮件地址进行编码的GetExchangeEncodedRecipient
辅助方法。
public static string GetExchangeEncodedRecipient(string recipient) {
int atIdx = recipient.LastIndexOf('@');
if (atIdx < 0) {
throw new ArgumentException("Unable to parse domain portion of \"recipient\" email address.");
}
string namepart = recipient.Substring(0, atIdx);
string domainPart = recipient.Substring(atIdx + 1);
//need to encode any special characters in the domain name
System.Globalization.IdnMapping punycode = new System.Globalization.IdnMapping();
domainPart = "@" + punycode.GetAscii(domainPart);
return String.Concat(namepart.Select(c => GetExchangeEncodedChar(c))) + domainPart;
}
private static string GetExchangeEncodedChar(char c) {
string encodedChar = c.ToString();
int charASCIICode = (int)c;
//Encode according to RFC5321, https://tools.ietf.org/html/rfc5321#section-4.1.2
// which references rfc3461 "xtext" format. https://tools.ietf.org/html/rfc3461#section-4
if(charASCIICode >= 33 && charASCIICode <= 126 && c != '+' && c != '=')
{
//This is a character in the valid 33-126 ASCII range for email addresses, which does not need encoded.
return c.ToString();
}
else if(c == '/'){
//A forward slash (/) is replaced by an underscore (_).
return "_";
}
else {
return "+" + ((int)c).ToString("x2").ToUpper();
}
}
然后您可以使用GetExchangeEncodedRecipient
对地址进行编码。这是一个例子:
string recipient = @"user1æøå@dømain.com";
string encodedAddress = GetExchangeEncodedRecipient(recipient);
Console.WriteLine("Original: {0}, Encoded: {1}", recipient, encodedAddress);
对于上面的示例收件人,将输出:
原文:user1æøå@dømain.com,编码:user1 + E6 + F8 + E5@xn--dmain-vua.com
如果你使用的“普通”电子邮件地址不包含“普通”ASCII范围之外的任何字符,那么它会返回相同的字符串。
原文:jsmith01@gmail.com,编码:jsmith01@gmail.com