验证 EWS 或 EWS 托管 API 调用的结果
了解如何验证 EWS 或 EWS 托管 API 调用的结果。
当无法正常工作时,通过检查应用程序通过网络发送的 SOAP 请求以及服务器正在发送回的响应,有助于查看发生了什么情况。 用于排查 EWS 应用程序故障的工具和资源文章包含工具链接,以帮助捕获和查看这些 SOAP 请求。 收到请求和响应后,如何验证发送到服务器的请求是否已正确处理? 继续阅读以了解。
如果要发送 EWS 请求,则将通过检查响应中每个响应消息的 ResponseClass 属性来开始验证。 这会告诉你是否已成功完成对每个项的操作。
如果使用 EWS 托管 API 发送请求,则可以使用响应对象执行一些验证,具体取决于方法调用的对象。 但是,由于 SOAP 响应包含 EWS 托管 API 响应对象中包含的内容的超集,因此你可能也想要查看 SOAP 响应。 由于 SOAP 响应通常可以包含比 EWS 托管 API 响应对象更多的信息,因此请使用 SOAP 响应开始验证。
验证 SOAP 响应的结果
收到 SOAP 响应时,首先要查看的是ResponseClass 属性。 此属性包含在ResponseMessages 元素中的每个ResponseMessageType> 实例中,如以下示例所示。
<s:Body>
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
…
由于 SOAP 响应可能在单个 SOAP 响应中包含多个响应消息,因此请务必单独检查每个响应消息。
如果使用包含ResponseClass作为操作响应的一部分的操作,如下所示,你可能只想检查操作的ResponseClass。
<soap:Body>
<m:AddDelegateResponse xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
ResponseClass="Success"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
…
但是,操作状态仅反映顶级响应的形状,不反映所有单独消息响应的状态。 在下面的示例中,AddDelegateResponse操作具有ResponseClassSuccess, 但基础DelegateUserResponseMessageType 元素具有ResponseClass 值错误。
<soap:Body>
<m:AddDelegateResponse xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
ResponseClass="Success"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ResponseMessages>
<m:DelegateUserResponseMessageType ResponseClass="Error">
<m:MessageText>The user is already a delegate for the mailbox.</m:MessageText>
<m:ResponseCode>ErrorDelegateAlreadyExists</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
</m:DelegateUserResponseMessageType>
</m:ResponseMessages>
</m:AddDelegateResponse>
</soap:Body>
因此,对于 SOAP EWS 响应, 不能依赖操作的ResponseClass - 必须查看每个响应消息的ResponseClass,以确定操作在处理项目时是否遇到任何错误。
正在验证是否成功
如果每个ResponseClass每个Respon 的属性seMessage属性设置为Success,已成功完成对所有项的操作, 你可以继续执行下一个任务。
以下示例演示了对GetItem操作请求的成功响应,以检索单个项。 请注意,当ResponseClass设置为Success, 关联的ResponseCode始终设置为NoError。
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="Er5bAAA="
ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAhE0/M" />
<t:Subject>Dinner Party</t:Subject>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
以下是对GetItem操作请求的成功响应,以检索多个项。 每个GetItemResponseMessage元素都有一个ResponseClass/aSuccess。
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="Er5bAAA="
ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAhE0/M" /
<t:Subject>Dinner Party</t:Subject>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="3c66AAA="
ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAc3kqm" />
<t:Subject>Company Soccer Team</t:Subject>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
处理错误和警告
收到响应时,ResponseClass 属性设置为Error,则操作在一个或多个项上未成功完成。 更正此问题,然后重试你的请求,或请求失败的部分。 ResponseClass属性值警告值仅由 ResolveNames 操作返回,并指示无法将实体解析为唯一标识。 对于所有其他操作,可以忽略它。
在以下响应中,ResponseClass 属性的值为 Error。
<m:GetItemResponseMessage ResponseClass="Error">
<m:MessageText>Property is not valid for this object type.</m:MessageText>
<m:ResponseCode>ErrorInvalidPropertyRequest</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
<m:MessageXml>
<t:FieldURI FieldURI="meeting:AssociatedCalendarItemId" />
</m:MessageXml>
<m:Items />
</m:GetItemResponseMessage>
在此示例中,EWS 提供了有关调试问题的线索。 当 ResponseClass 属性的值为 Error时,响应中将包含以下附加元素(如果适用):
MessageText —描述错误。
ResponseCode —包含可用于查找其他故障排除资源的错误代码。
MessageXml —标识导致错误的元素。
DescriptiveLinkKey —闲置。
可以使用这些元素中提供的信息来调查你的问题。 在前面的示例中,MessageText指示属性对对象类型无效。 请求是获取电子邮件,但属性集包含AssociatedCalendarItemId,它仅对约会项目有效。
以下示例显示在批处理操作中收到的错误,该操作用于获取多个电子邮件项。 已成功检索第一项,ResponseClass设置为Success。 找不到第二项,ResponseClass设置为错误。
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="Er5cAAA="
ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAhE0/O" />
<t:Subject>Business plans</t:Subject>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
<m:GetItemResponseMessage ResponseClass="Error">
<m:MessageText>The specified object was not found in the store.</m:MessageText>
<m:ResponseCode>ErrorItemNotFound</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
<m:Items />
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
如果无法按请求处理批处理请求中的一个或多个项,则会为每个失败的项返回错误,并且批处理中的其余项将按预期进行处理。 如果项目已删除,因此无法发送、检索或更新,或者项目移动到其他文件夹,因此具有新项 ID,则可能会发生批处理失败。 由于某些项的操作将完成,并且无法处理一个或多个项时不返回错误,因此请务必先检查每个ResponseClass属性,然后再继续下一个操作。
如果响应元素提供的信息无法帮助你更正请求或取消阻止你,请参阅Next 步骤。
验证 EWS 托管 API 方法调用的结果
如果使用 EWS 托管 API 并对ExchangeService 对象调用方法, 你的方法可能会返回ServiceResponseCollection 对象,其中包含ServiceResponse 对象的集合, 或派生自 ServiceResponse 对象的集合。 ServiceResponseCollection并且包含ServiceResponse 对象包含有关方法调用结果的信息,可用于验证结果。
如果使用 EWS 托管 API 并对Item 对象调用方法, 或派生对象之一,如果方法未成功完成,该方法可能不会返回响应对象来检查是否成功,但会引发Exception。
正在验证是否成功
使用 EWS 托管 API 的一个好处是,它在一个响应中处理多个项时提供总体状态。 因此,如果调用的方法返回ServiceResponseCollection,则可以检查OverallResultServiceResponseCollection 的属性等于ServiceResult.Success。 如果是这样,则批处理进程中的所有项均已成功完成;无需单独检查每个ServiceResponse 对象。 如果OverallResult属性未设置为ServiceResult.Success, 必须处理错误或警告。
如果调用的方法未返回ServiceResponseCollection, 但返回ServiceResponse 对象时,必须检查Result 属性的值。 如果Result值设置为success,则你知道该方法已成功完成。
如果调用的方法没有返回值,则实际上无法通过 EWS 托管 API 检查是否成功。 只要不引发异常,就可以假定方法已成功完成。 对于其他验证,还可以检查 SOAP 响应以验证结果。
处理错误、警告和异常
如果 EWS 托管 API 代码引发Exception,则可以使用Exception.Message 值来确定错误的来源。 Message 属性包含基础 SOAP 响应中MessageText 元素的内容。 此外,如果异常的类型ServiceResponseException 对象, 最常见的异常之一,还可以检索基础 SOAP ResponseCode> 元素中包含的ErrorCode 元素, Response 属性,用于标识关联的ServiceResponse 对象。 下面的代码演示如何捕获和显示ServiceResponseException的内容。
try
{
…
}
catch (ServiceResponseException ex)
{
Console.WriteLine("Error code: " + ex.ErrorCode);
Console.WriteLine("Error message: " + ex.Message);
Console.WriteLine("Response: " + ex.Response);
}
如果调用的方法返回 ServiceResponseCollection,并且 OverallResult 属性的值等于 Warning 或 Error,则必须循环访问 ServiceResponseCollection 中的每个对象以查找错误。 OverallResult属性设置为Warning如果至少有一个响应具有其Result值设置为Warning所有其他响应的Result值设置为Success。 OverallResult 属性设置为错误如果位于 至少有一个响应的Result 值设置为Error。 当OverallResult设置为Warning或Error, 以下属性在ServiceResponse对象上根据需要设置:
ErrorCode —包含可用于查找其他故障排除资源的错误代码。
ErrorDetails —包含有关某些ErrorCodes的错误的详细信息。 例如,当错误代码ErrorRecurrenceHasNoOccurrence, ErrorDetails 将包含 <键EffectiveStartDate和EffectiveEndDate。
ErrorMessage —描述错误。
ErrorProperties —如果可用,则标识导致错误的属性。 例如,当错误代码 ErrorInvalidPropertyForOperation时, ErrorProperties 包含对请求无效的属性的定义。
Result —遇到问题时,包含Error 或Warning。
如果ServiceResponse属性提供的信息不足以更正方法调用或取消阻止你, 请参阅 Next 步骤以深入了解有关 ErrorCode 值的详细信息。
可以在以下主题中查找其他疑难解答信息:
此外,根据你尝试在请求中完成的操作,你可能会在以下主题中找到有关错误代码的其他有用信息: