Solved

How do you query an MS Exchange 2000 mailbox using ADO.NET within a VB.NET application?

Posted on 2004-10-07
8
428 Views
Last Modified: 2010-05-18
Hello,

I am currently querying an Exchange 2000 mailbox using an ADO connection, but have been trying to find a way to utilize ADO.NET.  A database connection I have to an Oracle server, was extremely easy to set up using the connection wizards in VS.NET 2003, and I can't help but think there is a method for Exchange which is just as simple.  When I try to establich a connection to the Exchange server, I'm unable to find a suitable provider.  The existing code is as follows:

      Dim objConnection As ADODB.Connection = New ADODB.Connection
      Dim objRecordSet As ADODB.Recordset = New ADODB.Recordset

      strUrl = "http://" + strServerName + "/Exchange/" + strMailBoxName + "/Inbox"

      'Open connection
      objConnection.Provider = "MSDAIPP.dso"
      objConnection.Open(strUrl, strAdUserName, strAdUserPassword, -1)

      'Build the SQL query
      strSql = ""
      strSql = "SELECT "
      strSql = strSql + " ""DAV:href"""
      strSql = strSql + ", ""DAV:displayname"" "
      strSql = strSql + ", ""urn:schemas:httpmail:from"" "
      strSql = strSql + ", ""urn:schemas:httpmail:subject"" "
      ...
      strSql = strSql + ", ""urn:schemas:httpmail:textdescription"" "
      strSql = strSql + ", ""RESOURCE_PARENTNAME"" "
      strSql = strSql + " FROM SCOPE ('deep traversal of " + """"
      strSql = strSql + strUrl + """') "
      strSql = strSql + " WHERE ""DAV:ishidden"" = false"

      'Open the recordset
      objRecordSet.Open(strSql, objConnection, ADODB.CursorTypeEnum.adOpenUnspecified, ADODB.LockTypeEnum.adLockOptimistic, 1)

Any advice would be greatly appreciated, as the deployment of my application is only delayed by this issue.  Thanks.
0
Comment
Question by:esdTeamsters
8 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12251827
Is this from ASP.NET solution?

Bob
0
 
LVL 18

Expert Comment

by:tusharashah
ID: 12251897
Check out this article with some sample code:

http://www.wimdows.net/articles/article.aspx?aid=13

-tushar
0
 

Author Comment

by:esdTeamsters
ID: 12252038
Bob,

It's a Visual Basic.NET solution created in Visual Studio.NET 2003.


Tushar,

Thanks for the article - it'll come in handy in the near future when I dive deeper into Active Directory queries.  But for the time being, I'm dealing solely with Exchange.  Is it possible to query an Exchange Mailbox Store using the same methods as Active Directory?  Thanks.
0
ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

 

Author Comment

by:esdTeamsters
ID: 12254186
After searching other postings on this topic, I found the following:

http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20815034.html

I converted the syntax to VB.NET but receive an error stating that 'Exoledb is not a registered provider on the local machine.'  Apparently it only exists on Exchange servers.  I have the dll but don't know if there is a way to force the registering of a new provider, or if there is a usable replacement.  Any ideas?
0
 
LVL 6

Expert Comment

by:etmendz
ID: 12256952
I made mine work and I can access the Exchange Server 2000 for as long as it is set to enable OWA or webDAV. You may update the HOST file to point an IP address to say a server name or an OWA address if necessary.

You need to use ADODB and CDO (reference C:\Program Files\Common Files\Microsoft Shared\CDO\CDOEX.DLL to create a CDO interop). Note that CDOEX.DLL comes with installing Office Outlook XP. Note also that using CDOEX.DLL is not a promised solution as Microsoft claims it is not designed to be used for a developer's purpose. Microsoft recommends that it can only be used as SDK on the same machine where Exchange Server is installed. I used it anyways on my PC (at my own risk). Surprisingly, it works for as long as you open only one (1) connection to the Exchange Server at any given time.

Anyways, here's how I did it:

You'll need:

Dim poRecord As ADODB.Record
Dim poRecordset As ADODB.Recordset
Dim poRecordMessage As ADODB.Record
Dim poMessage As CDO.Message

You use poRecord to open a connection:

Dim psEMailboxURL As String
psEMailboxURL = "http://ServerNameOrIPOrOWAAddress/MailboxName/"
poRecord.Open(psEMailboxURL & "Inbox", , , , , userID, password)

You use poRecordset to open a recordset:

If poRecord.State = ADODB.ObjectStateEnum.adStateOpen Then
 Dim psEMailboxQuery As String
 psEMailboxQuery = "SELECT * " & _
                              "FROM """ & psEMailboxURL & "Inbox"" " & _
                              "WHERE ""urn:schemas:httpmail:read"" = false"
 poRecordset.Open(psEMailboxQuery, poRecord.ActiveConnection)
End If

You use poRecordMessage and poMessage to extract a message from poRecordset:

poRecordMessage.Open(poRecordset, _
 poRecord.ActiveConnection, _
 ADODB.ConnectModeEnum.adModeReadWrite, _
 ADODB.RecordCreateOptionsEnum.adFailIfNotExists)
poMessage.DataSource.OpenObject(poRecordMessage, "_Record")

Be sure to add in your exception handling here and there. Be sure to close where Close() is a method of an object. Refer to the Exchange SDK for information about the many Exchange Store Schema properties (great samples too). Note that this solution relies on webDAV which according to some documents may not be supported in future versions of the Exchange Server.

Have fun.
0
 

Author Comment

by:esdTeamsters
ID: 12262208
Thanks for the info etmendz.

I've been able to pull down data with no problem, but my real dilemma is being able to efficiently *update* Exchange.  Is it possible to do this by simply updating the recordset?  The only information I've been able to find on this in the past, has been to update/create one object at a time.  And that was done using 'System.Net.HttpWebRequest' and alot of XML - which I'm trying to avoid at this point if at all possible.  I'd like to simply 'resync' the local recordset with the remote data source - if there is such a method.  The non-working code I have now is:

      Dim objConnection As ADODB.Connection = New ADODB.Connection
      Dim objRecordSet As ADODB.Recordset = New ADODB.Recordset

      strUrl = "http://" + strServerName + "/Exchange/" + strMailBoxName + "/Inbox"

      'Open connection
      objConnection.Provider = "MSDAIPP.dso"
      objConnection.Open(strUrl, strAdUserName, strAdUserPassword, -1)

      'Build the SQL query
      strSql = ""
      strSql = "SELECT "
      strSql = strSql + " ""DAV:href"""
      strSql = strSql + ", ""DAV:displayname"" "
      strSql = strSql + ", ""urn:schemas:httpmail:from"" "
      strSql = strSql + ", ""urn:schemas:httpmail:subject"" "
      ...
      strSql = strSql + ", ""urn:schemas:httpmail:textdescription"" "
      strSql = strSql + ", ""RESOURCE_PARENTNAME"" "
      strSql = strSql + " FROM SCOPE ('deep traversal of " + """"
      strSql = strSql + strUrl + """') "
      strSql = strSql + " WHERE ""DAV:ishidden"" = false"

      'Open the recordset
      objRecordSet.Open(strSql, objConnection, ADODB.CursorTypeEnum.adOpenUnspecified, ADODB.LockTypeEnum.adLockOptimistic, 1)

      objRecordSet.AddNew()
      objRecordSet.Fields("urn:schemas:httpmail:subject").Value = "Test Value"
      ...
      objRecordSet.Fields("urn:schemas:httpmail:textdescription").Value = "Test Value"
      objRecordSet.Update()

      objRecordSet.Close()
      objConnection.Close()


This returns an error stating that 'The recordset doesn't support updating which may be a limitation of the Provider or Lock Type.'  Does anyone know of a provider that supports this?

I did some more digging and found a way to move the data queried in my existing ADO connection/recordset into an ADO.NET DataSet for manipulation.  Unfortunately, I'm finding out that there is no direct support between Exchange and ADO.NET.  I can deal with this if there is a way to handle everything (querying/updating) using ADO.  Thanks again.
0
 
LVL 6

Accepted Solution

by:
etmendz earned 500 total points
ID: 12273626
I am able to perform simple operations using my technique. For example, I can use the ADODB.Record object poRecordMessage.MoveRecord to move the record from Inbox to the Deleted Items folder. You might want to explore the features of this object.

I am not aware of any Exchange Server 2000 components built for .Net. ADO.Net is also not known to support Exchange Server 2000 as directly as ADO. So I guess you'll have to settle with Exchange -> ADO -> ADO.Net -> ADO -> Exchange.

From the sample code you have above, it seems that you want to add objects to an Exchange Store. CDO and MAPI may provide these abilities but I suggest that you focus on CDO. These are not .Net but you can create interops to make them work in .Net. There are also ways that uses webDAV specific commands. These are all available in the Exchange SDK documentation and samples. I suggest that you check them out.

Here are some tips. I am assuming you are NOT doing this on the same Exchange Server. So if your copy of CDOEX.DLL is OK with you, focus on samples that use CDOEX.DLL. If you are on Exchange Server, then check out Exchange SDK documentation. It describes the providers and built-in components you can use. Again, these are all COM based and you'll need to create interops to use them in .Net.

Have fun.
0
 

Author Comment

by:esdTeamsters
ID: 12449625
Thanks for all the input etmendz.  Unfortunately I think you're right in that there is no direct support between ADO.NET and Exchange - hopefully that will change in the future.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question