使用:EWS 1.1、Exchange server 2010 SP1、VB.Net
我正在使用 EWS 通过 Windows 服务为我公司的 2000 多个用户创建日历约会,我开发了一个 Windows 服务,当用户在我们自己的公司企业应用程序中创建或更新他们的约会时,该服务将为他们创建或更新约会。我安装了 Windows 服务,该服务由在 Exchange server 2010 上具有模拟权限的服务帐户启动。该服务将调用 DLL 为用户在 Exchange 中创建或更新约会。
- 使用版本 Exchange2010_SP1 初始化 ExchangeService
- UseDefaultCredentials=True(登录的用户有模拟权限)
- 使用 ImpersonatedUserId 模拟我要创建日历约会的用户
- 初始化一个 Appointment 对象(appointment = new Microsoft.Exchange.WebServices.Data.Appointment)
- 使用值填充 Appointment 对象(例如,属性 Start、End、IsAllDayEvent、Body、Sensitivity、Subject、Location)
- 使用 Appointment.Save(WellKnownFolderName.Calendar, SendInvitationsMode.SendToNone) 创建约会
- 当用户在我们的企业应用程序中更新他们的约会时,我使用 Appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone)
以下是一些代码片段:
Try
'Initialize the Exchange service
exchangeService = New ExchangeService(ExchangeVersion.Exchange2010_SP1)
impersonationContext = CType(System.Web.HttpContext.Current.User.Identity, System.Security.Principal.WindowsIdentity).Impersonate
exchangeService.UseDefaultCredentials = True
exchangeService.ImpersonatedUserId = New ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@domain.com")
System.Net.ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf ValidateCertificate)
exchangeService.Url = New Uri("https://server/ews/Exchange.asmx")
'Create or Update appointment
If newAppointment Then
appointment = New Appointment(exchangeService)
Else
appointment = Appointment.Bind(exchangeService, New ItemId(appointmentId))
End If
With appointment
.Subject = *subject*
.Start = *start date*
.End = *end date*
.Body = *msgbody*
.Location = *location*
If newAppointment Then
.Save(WellKnownFolderName.Calendar, SendInvitationsMode.SendToNone)
Else
.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone)
End If
End With
Catch ex As Exception
'Throw exception here
Finally
If Not impersonationContext Is Nothing Then
impersonationContext.Undo()
End If
End Try
模拟是因为当从 Windows 服务调用时,当前的 WindowsIdentity 是 IIS AppPool,所以我需要模拟服务帐户,然后才能初始化交换服务并创建/更新约会。
每次需要创建或更新约会时,都会创建新的交换服务。
大多数情况下该过程进展顺利,但有时我会收到一个我不知道为什么以及导致它的原因的 ServiceRequestException:
Microsoft.Exchange.WebServices.Data.ServiceRequestException:请求失败。底层连接已关闭:发送时发生意外错误。---> System.Net.WebException:底层连接已关闭:发送时发生意外错误。---> System.ObjectDisposedException: Safe handle has been closed at System.Security.Principal.Win32.ImpersonateLoggedOnUser(SafeTokenHandle hToken) at System.Security.Principal.WindowsIdentity.SafeImpersonate(SafeTokenHandle userToken, WindowsIdentity wi, StackCrawlMark& stackMark) at System. Security.Principal.WindowsIdentity.Impersonate(StackCrawlMark& stackMark) 在 System.Security.SecurityContext.SetSecurityContext(SecurityContext sc, SecurityContext prevSecurityContext, StackCrawlMark& stackMark) 在 System.Threading.ExecutionContext。