调用EWS API发送邮件报服务器协议违规错误求助
问题说明
开发基于EWS API的邮件发送系统时,每次执行发送操作都会返回如下错误:
请求失败,服务器提交了协议违规。Section=ResponseHeader Detail=CR must be followed by LF
原实现代码
Dim mailFrom As String = "user@domain.com" Dim mailPass As String = "userPass" Try Dim service As ExchangeService = New ExchangeService() Dim mail As New EmailMessage(service) service.TraceEnabled = True service.Credentials = New WebCredentials(mailFrom, mailPass) service.Url = New Uri("https://email.domain.com/autodiscover/autodiscover.xml") mail.From = mailFrom mail.ToRecipients.Add(Email.txtEmailRecipient.Text) mail.Subject = Email.txtEmailSubject.Text mail.Body = Email.txtEmailBody.Text mail.SendAndSaveCopy() MsgBox("Email sent.") Catch ex As Exception MsgBox(ex.Message) End Try
解决方案
这个报错本质是服务端返回的HTTP响应头不符合规范,出现了单独的CR回车符没有跟随LF换行符,被.NET的HTTP请求校验拦截,可按以下顺序排查修复:
- 不要手动硬编码Autodiscover地址:当前代码直接写死自动发现端点路径,不符合EWS最佳实践,很容易命中返回不规范响应的非业务端点。删除手动赋值
service.Url的代码,替换为官方自动发现方法:
该方法会自动探测当前账号对应的合法EWS服务端点,避免访问错误的接口地址。service.AutodiscoverUrl(mailFrom, Function(redirectUrl) True) - 若因网络限制必须手动指定服务地址,可通过配置关闭.NET的严格HTTP头校验。在项目的app.config/web.config中添加以下配置节点,跳过响应头的CRLF格式校验:
<configuration> <system.net> <settings> <httpWebRequest useUnsafeHeaderParsing="true" /> </settings> </system.net> </configuration> - 初始化ExchangeService实例时明确指定Exchange版本,避免默认低版本兼容模式和服务端产生通信兼容问题,示例:
' 替换为实际使用的Exchange服务器对应版本 Dim service As ExchangeService = New ExchangeService(ExchangeVersion.Exchange2016) - 修正发件人赋值逻辑:直接给
mail.From传字符串在部分版本EWS托管API中会出现隐式转换异常,建议显式传入EmailAddress对象:mail.From = New EmailAddress(mailFrom)
内容的提问来源于stack exchange,提问作者Mauzuk
相关产品推荐
相关产品推荐

