Email Management software nowadays connect to exchange servers and archives e-mails based on some criteria. Have you ever wondered how the software is able to connect to Microsoft Exchange and manage the capture of e-mails?
this article is the introduction to the know-how, we will be exposed to the new Exchange Managed web services API that allows you to do awesome tasks on top of exchange.
let's do it!
Prepare the Environment
- Install Microsoft Exchange Web Services Managed API from the following Web Site:
Create a New Visual Basic .Net windows Application Project
- Open A New Microsoft Visual Basic .Net Windows Project, I am using VS 2010 in this sample
- Add a reference to “Microsoft.Exchange.WebServices” , browse to the reference file in “<Install Drive>\Program Files\Microsoft\Exchange\Web Services\1.1”
- Open a New windows Form, add a button, text boxes as follows:
The 4 text boxes will represent the environment data; it will have the information about the exchange server, the admin credentials that we will use to connect to that exchange server, and the user account mail box that we will read messages from.
Control Label | Text Box Control Name | Usage |
Exchange Server Name | txtExchangeServerName | This is going to have the value of the FULL exchange server name in the following format: <ServerName>.<DomainName>.com |
Admin Account Name | txtAdminAccountPassword | This is the administrative user name that will connect to the exchange server, it should have admin privileges on the exchange server, |
Admin Account Password | txtAdminAccountPassword | The password of the admin account |
User / Mailbox Account | txtAccountName | This is the mailbox account that we will fetch emails from |
o Exchange Server Name text Box: txtExchangeServerName.
o Text Box: txtExchangeAdminName
o Admin Account Password: txtAdminAccountPassword
o User / Mailbox Account: txtAccountName
- Add a Grid control to the form, the grid control will show the e-mails of the selected mailbox.
- Go to source code and import the following classes
Usage | |
Imports Microsoft.Exchange.WebServices.Data | Will be used to reference the following objects: - Exchange Service - Folder - SearchFilter - ItemView - FindItemsResults(Of Item) - EmailMessage - WellKnownFolderName - LogicalOperator - EmailMessageSchema |
Imports System.Net | Will be used to reference the following Objects: - NetworkCredential |
Connect to mailbox and fetch emails
In this section, I will demonstrate the code to connect to a mailbox and fetch the emails.
Open source control, open the buttun1_click event, then write the following code to instantiate an abject for the exchange service, this object will take care of establishing the connection to the exchange server:
Dim oService As ExchangeService = New ExchangeService(ExchangeVersion.Exchange2010)
It is to that I am using exchange server 2010 in my sample. Should you need to connect to 2007, you will have to change the parameter ExchangeVersion.Exchange2010 to the 2007 option
Then, create a variable to hold the URI address, pass the variable to the exchange service object:
Dim strServerURI As String = "https://" & txtExchangeServerName.Text & "/ews/exchange.asmx"
oService.Url = New Uri(strServerURI)
The URI address is going to be as this format: https://rsvr1.rdom.com/ews/exchange.asmx where rsvr1.rdom.com is the full name of the exchange server. In order to double check that it is the correct format, take the URL and insert it in the browser, if it returns XML WSDL information, it means it is working and the connectivity is OK, if it does not return valid data, then there is definitely a problem with the server or with the URL itself.
We need now to pass the admin credential and the domain name information; this information will be used when connecting to the exchange server
'---pass the Admin credential and domain information for admin connectivity
Dim strDomainName As String = Split(txtExchangeServerName.Text, ".")(1)
oService.Credentials = New NetworkCredential _
(txtExchangeAdminUserName.Text, txtExchangeAdminPassword.Text, strDomainName)
Now you need to connect to the user mailbox:
'---conenct to the user mailbox
Dim strMailboxUser As String = txtAccountName.Text
oService.ImpersonatedUserId = New ImpersonatedUserId(ConnectingIdType.SmtpAddress, strMailboxUser)
Then you need to select which folder you need to access, in our example, we will access the user “Inbox” folder:
Now comes the trick of the day, if you run the code until above point, you will be receiving the following error:
This happens when you are connecting to exchange in a secured socket layer connectivity, I have spent some time looking for a solution to this issue, until I knew that you will need to override the way that handles the secured connectivity, we will be telling the environment to accept my connection to the exchange server. In order to do this, I have created a class that will take care of this functionality:
Imports System.Net
Imports System.Net.Security
Imports System.Security
Imports System.Security.Cryptography.X509Certificates
Public Class TrustAllCertificatePolicy
Public Shared Sub OverrideCertificateValidation()
ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf RemoteCertValidate)
End Sub
Private Shared Function RemoteCertValidate(ByVal sender As Object, ByVal cert As X509Certificate, ByVal chain As X509Chain, ByVal [error] As System.Net.Security.SslPolicyErrors) As Boolean
Return True
End Function
End Class
Then in the code, put the following line before the code that connects to the user inbox, so t will be as follows:
TrustAllCertificatePolicy.OverrideCertificateValidation()
This would solve the problem, and now let us continue with the email fetching.
To get e-mails, you will need to establish a search filter, search filters is a good way of sending multiple criteria to exchange server to get the requested e-mails, in our case here, we need to get the read and unread e-mails (all e-mails)
We will pass the search filters as array of filters, as follows:
Dim arrSearchFilter(1) As SearchFilter
arrSearchFilter(0) = New SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, True)
arrSearchFilter(1) = New SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, False)
Now execute the search folder on the user inbox
Dim oSearchFilter As SearchFilter = Nothing
oSearchFilter = New SearchFilter.SearchFilterCollection(LogicalOperator.Or, arrSearchFilter)
The rest of the code is to create a DataTable with columns, and bind the results to it and display it in grid.
Dim oView As ItemView = New ItemView(20)
'---Fire the query for the unread items
oResults = oService.FindItems(WellKnownFolderName.Inbox, oSearchFilter, oView)
Dim oMessage As EmailMessage = Nothing
oMessageCollection = New DataTable
Dim oColumn As New DataColumn
oColumn.ColumnName = "ID"
oColumn.AutoIncrement = True
oMessageCollection.Columns.Add(oColumn)
oColumn = New DataColumn
oColumn.ColumnName = "Subject"
oMessageCollection.Columns.Add(oColumn)
oColumn = New DataColumn
oColumn.ColumnName = "From"
oMessageCollection.Columns.Add(oColumn)
oColumn = New DataColumn
oColumn.ColumnName = "Date Received"
oMessageCollection.Columns.Add(oColumn)
Dim oRow As DataRow
For Each oMessage In oResults
oRow = oMessageCollection.NewRow
oRow("Subject") = oMessage.Subject
oRow("From") = oMessage.From.Name
oRow("Date Received") = oMessage.DateTimeReceived
oMessageCollection.Rows.Add(oRow)
oRow = Nothing
Next
'---Loop through the items and do whatever is required.
DataGridView1.DataSource = oMessageCollection
DataGridView1.DataSource = oMessageCollection
5 comments:
Very good article. But it would be appreciated to explain howto impersonate useraccounts, otherwise it ends in an error 401.
Filmproduktion von VerTrend Media Production
Thank you for the information. You have a very good article. I found it informative and useful. Keep up the good work and God bless!
www.gofastek.com
Post a Comment