Windows环境

邮件发送失败

Exchange 2010和2013可以限制用户发送的邮件数量;通过Power Shell命令新建一条策略规则,给recipientratelimit和messageratelimit两个参数赋予一定的值,再给用户应用此规则即可实现限制用户发送量的效果。
参数说明:
messageratelimit:限制用户每分钟可以发送的最大邮件数量,如每分钟内发送的量超过限制,邮件将停留在发件箱,邮件被延迟到下一分钟,并最终被发送成功。
recipientratelimit:限制用户24小时内的发送的最大邮件数量,如发送超过限制,将收到超过限额的NDR退信消息。
注:通讯组(包括动态通讯组)算一个收件人。

参考:Exchange2010\2013限制用户每分钟与每天发送邮件的数量

异常处理要注意

有些方法 执行不成功,例如:邮箱服务器没有此itemId,会报错,直接抛出ServiceResponseException异常,而不是返回null就行

try
  {
      Item item = await Item.Bind(service, itemId, propertySet);
      EmailMessage message = item as EmailMessage;
      return message;
  }
   catch (ServiceResponseException srex)
   {
      Debug.WriteLine($"GetEmailSummary:{srex.ErrorCode},{srex.Message}");
      return null;
    }
   catch (Exception ex)
   {
      throw ex;
    }

或者直接,让外层去捕获异常,外层记录异常日志。。

try
   {
      Item item = await Item.Bind(service, itemId, propertySet);
      EmailMessage message = item as EmailMessage;
      return message;
    }
     catch (Exception ex)
     {
        throw ex;
      }

在获取 标记Flag的邮件时报错

1、System.AggregateException: One or more errors occurred. (该属性不能用于此类型的限制。)

代码:searches.Add(new SearchFilter.IsEqualTo(ItemSchema.Flag, true));  //星标

ItemSchema.Flag

定义Flag属性。 标记字段适用于以Exchange Server 2013为目标的Exchange Online客户端和Exchange版本。

2、System.AggregateException: One or more errors occurred. (扩展的属性特性组合无效。)

new SearchFilter.IsEqualTo(new ExtendedPropertyDefinition(0x1090, MapiPropertyType.Boolen), true))

改为

new SearchFilter.IsEqualTo(new ExtendedPropertyDefinition(0x1090, MapiPropertyType.Integer), true))

3、System.AggregateException: One or more errors occurred. (指定的值对属性无效。)

new SearchFilter.IsEqualTo(new ExtendedPropertyDefinition(0x1090, MapiPropertyType.Integer), true))

改为

new SearchFilter.IsEqualTo(new ExtendedPropertyDefinition(0x1090, MapiPropertyType.Integer), 2));

A time zone with the specified ID could not be found

将service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

改为 service = new ExchangeService();   不指定则用最新的版本

The request failed.[Content-Type]

具体:The request failed. Cannot process the message because the content type 'text/plain; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'

在直接引用Microsoft.Exchange.WebServices.NETStandard 包的时候没有问题,

但是在 引入源码后,编译为dll去调用的时候,报错。

【因为 引用的是两套代码,引入的包里面的代码是官网(要从包的dll去反编译查看出)的:https://github.com/OfficeDev/ews-managed-api

而你引入的源码很可能是https://github.com/sherlock1982/ews-managed-api

参考:https://stackoverflow.com/questions/54948180/ews-httpheader-content-type

Exchange开发常见报错

在sherlock1982(github.com/sherlock1982/ews-managed-api)的EWS分支中找到EwsHttpWebRequest.cs类。在GetResponse方法中,在设置消息内容之后立即进行设置(第91行):

message.Content.Headers.Clear( );
message.Content.Headers.Add(“ Content-Type”,“ text / xml; charset = utf-8”);

问题是因为HttpRequestMessage的内容类型不正确,而不是请求本身。 希望这会有所帮助-我知道,答案要晚一年了... :) –

The SSL connection could not be established, see inner exception

在直接引用Microsoft.Exchange.WebServices.NETStandard 包的时候没有问题,

但是在 引入源码后,编译为dll去调用的时候,报错。

场景:用邮箱host对应的ip去模拟登录时报错。

Httpclient想要实现相同的功能,需要在HttpClient中设置。

var handler = new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = delegate { return true; }
};

参考:HttpClient SSL connection could not be established error

修改源码:

EwsHttpWebRequest.cs类

internal EwsHttpWebRequest(Uri uri)
        {
            Method = "GET";
            RequestUri = uri;
            _httpClientHandler = new HttpClientHandler() {
                AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
     ServerCertificateCustomValidationCallback = delegate { return true; } //增加这一行
            };
            _httpClient = new HttpClient(_httpClientHandler);
        }

发加密签名邮件报错:必需的属性丢失

断点调试,去发现报错的位置,具体信息:

Exchange开发常见报错

看到ErrorCode:ErrorRequiredPropertyMissing

根据ErrorRequiredPropertyMissing去搜索,找到官网,

参考官网:https://docs.microsoft.com/zh-cn/exchange/client-developer/exchange-web-services/ews-property-related-errors

Exchange开发常见报错

定位到问题是Attachments的问题

需要调试下exchange的EmailMessage 中的Attachments 的属性是否都具有:

完整的应该是以下:

Exchange开发常见报错

获取邮件体 MIME 内容转换失败 ErrorCode = ErrorMimeContentConversionFailed

现象:在获取 未送达的邮件体时报的错。

Exchange开发常见报错

在Web上查看:如下

Exchange开发常见报错

可以改用以下方式重新获取

1、首先捕获异常ErrorMimeContentConversionFailed

catch (AggregateException ex)
            {
                var exception = ex.InnerException as ServiceResponseException;
                if (exception != null)
                    serviceError = exception.ErrorCode;
            }

2、  调用处:

EmailMessage emailMessage =  EWSItemHelper.GetEmailMessageBody(service, itemId, out serviceError);
                if (emailMessage == null)
                {
                    if (serviceError == ServiceError.ErrorMimeContentConversionFailed)
                    {
                        var mailDetail = new MailDetailModel(mailInfo);
                        mimeMessage = await DownloadMessage(service, mailDetail, itemId);
                    }
                }

3、  处理

/// <summary>

        /// 重新下载邮件信息

        /// </summary>

        /// <param name="exchangeService"></param>

        /// <param name="mailInfo"></param>

        /// <param name="itemId"></param>

        /// <returns></returns>

        private async Task<MimeMessage> DownloadMessage(

         ExchangeService exchangeService,

         MailDetailModel mailInfo,

         ItemId itemId)

        {

            var mail = await EWSItemHelper.GetEmailMessageBodyNew(exchangeService, itemId);

            List<FileAttachment> fileAttaches = new List<FileAttachment>();

            if (mail == null)

                return null;

            if (mail.Attachments != null && mail.Attachments.Count() > 0)

            {

                foreach (var attachment in mail.Attachments)

                {

                    if (attachment is FileAttachment)

                    {

                        FileAttachment fileAttachment = attachment as FileAttachment;

                        fileAttaches.Add(fileAttachment);

                    }

                }

            }

            var message = new MimeMessage();

 

            string name = string.Empty;

            string email = string.Empty;

 

            StringFormatHelper.GetNameAndEmailAddress_NotSplitEmail(mailInfo.MailFrom, ref name, ref email);

            message.From.Add(new MailboxAddress(name, email));

 

            if (!string.IsNullOrEmpty(mailInfo.MailTo))

            {

                //message.To.Add(new MailboxAddress("Alice", "alice@wonderland.com"));

            }

 

            if (!string.IsNullOrEmpty(mailInfo.MailCc))

            {

                //message.Cc.Add(new MailboxAddress("Alice", "alice@wonderland.com"));

            }

            message.Subject = mail.Subject;

            message.Date = mailInfo.MailDate;

 

            var builder = new BodyBuilder();

 

            // Set the plain-text version of the message text

            builder.HtmlBody = mail.Body.Text;

            //bool isSign = false;

            foreach (var attach in fileAttaches)

            {

                //if (attach.ContentType == "multipart/signed")

                //    isSign = true;

 

                // We may also want to attach a calendar event for Monica's party...

                if (attach != null)

                    builder.Attachments.Add(attach.Name, attach.Content);

            }

 

            // Now we just need to set the message body and we're done

            message.Body = builder.ToMessageBody();

 

            //if (isSign)

            //{

            //message.Body.Headers.Remove(HeaderId.ContentType);

            //message.Body.Headers.Add(HeaderId.ContentType, "multipart/signed");

            //}

 

            return message;

        }

/// <summary>

        /// 通过ItemId 获取邮件体

        /// </summary>

        /// <param name="service"></param>

        /// <param name="itemId"></param>

        /// <returns></returns>

        public static async Task<EmailMessage> GetEmailMessageBodyNew(ExchangeService service, ItemId itemId)

        {

            try

            {

                PropertySet properties = new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Body, ItemSchema.TextBody, ItemSchema.Subject, ItemSchema.HasAttachments, ItemSchema.Attachments, ItemSchema.ExtendedProperties);

                Item item = await Item.Bind(service, itemId, properties);

                if (item == null)

                    return null;

                EmailMessage message = item as EmailMessage;

                if (message == null)

                    return null;

                else

                    return message;

            }

            catch (Exception ex)

            {

                //throw ex;

            }

            return null;

        }
View Code

相关文章: