Solved

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

Posted on 2004-10-07
8
426 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
Comment Utility
Is this from ASP.NET solution?

Bob
0
 
LVL 18

Expert Comment

by:tusharashah
Comment Utility
Check out this article with some sample code:

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

-tushar
0
 

Author Comment

by:esdTeamsters
Comment Utility
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
 

Author Comment

by:esdTeamsters
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 6

Expert Comment

by:etmendz
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

743 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now