Access exchange e-mail in C#

2019-01-08 16:28发布

问题:

Do you know if there's a way?

I've used this library to access a pop3 server, but it doesn't work with an exchange server.

Do you know of any other library or piece of code that'll show me how to do it?

I cannot change any settings on the server.

回答1:

Depends on the Exchange version. WebDAV works with 2000 thru 2007, but Web Services requires 2007+.

Those are probably the easiest to get working. CDO is another option, but it's not supported from C# - so you'll have to go out of proc.

Exchange also has an OLEDB provider, but I've never used it - it is supported from .NET, however.



回答2:

If you use Exchange 2007 and have web services enabled, this is pretty easy. I added a 2.0-style classic Web Reference to my VS2008 project, and I can get mail messages like this:

// exchange 2007 lets us use web services to check mailboxes.
using (ExchangeServiceBinding exchangeServer = new ExchangeServiceBinding())
{
    ICredentials creds = new NetworkCredential("user","password");
    exchangeServer.Credentials = creds;
    exchangeServer.Url = "https://myexchangeserver.com/EWS/Exchange.asmx";
    FindItemType findItemRequest = new FindItemType();
    findItemRequest.Traversal = ItemQueryTraversalType.Shallow;

    // define which item properties are returned in the response
    ItemResponseShapeType itemProperties = new ItemResponseShapeType();
    itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
    findItemRequest.ItemShape = itemProperties;

    // identify which folder to search
    DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
    folderIDArray[0] = new DistinguishedFolderIdType();
    folderIDArray[0].Id = DistinguishedFolderIdNameType.inbox;

    // add folders to request
    findItemRequest.ParentFolderIds = folderIDArray;

    // find the messages
    FindItemResponseType findItemResponse = exchangeServer.FindItem(findItemRequest);

    // read returned
    FindItemResponseMessageType folder = (FindItemResponseMessageType)findItemResponse.ResponseMessages.Items[0];
    ArrayOfRealItemsType folderContents = new ArrayOfRealItemsType();
    folderContents = (ArrayOfRealItemsType)folder.RootFolder.Item;
    ItemType[] items = folderContents.Items;

    // if no messages were found, then return null -- we're done
    if (items == null || items.Count() <= 0)
        return null;

    // FindItem never gets "all" the properties, so now that we've found them all, we need to get them all.
    BaseItemIdType[] itemIds = new BaseItemIdType[items.Count()];
    for (int i = 0; i < items.Count(); i++)
        itemIds[i] = items[i].ItemId;

    GetItemType getItemType = new GetItemType();
    getItemType.ItemIds = itemIds;
    getItemType.ItemShape = new ItemResponseShapeType();
    getItemType.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
    getItemType.ItemShape.BodyType = BodyTypeResponseType.Text;
    getItemType.ItemShape.BodyTypeSpecified = true;

    GetItemResponseType getItemResponse = exchangeServer.GetItem(getItemType);
    ItemType[] messages = new ItemType[getItemResponse.ResponseMessages.Items.Count()];

    for (int j = 0; j < messages.Count(); j++)
        messages[j] = ((ItemInfoResponseMessageType)getItemResponse.ResponseMessages.Items[j]).Items.Items[0];

    return messages;
}

The "messages" variable will be an array of ItemType objects returned from exchange that have all the properties you'd expect for a mail message (Body, Attachments, etc.). I hope this helps!



回答3:

Using EWS directly in managed code (VB.net / C#) is clumsy to say the best.

I've been fumbling around with it for a few days now, and have come to the conclusion that it's better to build my own wrapper classes around the API, making the services usable in a line or two of code, not the page with the current implementation.

Guess what? Microsoft have beaten me to it: Exchange Web Services Managed API's first Release Candidate is available for download here.

Install, register the dll reference (\Program Files\Microsoft\Exchange\Web Services\1.0\Micorosft.Exchange.WebServices.dll), and import the namespace (Microsoft.Exchange.WebServices.Data) and you're ready to roll.



回答4:

I assume your issue is that your exchange server only support NTLM authentication and does not allow plain text authentication? Or you might not be using the proper username convention. For example you might try using the format username@domain where domain is the internal NT domain which might not be the same as your internet domain.

If that is the case then look for a library that supports NTLM.

Steps for testing via telnet

Go to command prompt type: telnet my.server.com 110 you should get a response from your exchange server like this +OK Microsoft Exchange Server 2003 POP3 server version 6.5.7638.1 (my.server.com) ready.

type: CAPA this should return the list of capabilities your exchange server supports. CAPA +OK Capability list follows TOP USER PIPELINING EXPIRE NEVER UIDL SASL NTLM .

Notice that mine does not show PLAIN

Here is a response from an email server that does+OK Dovecot ready. CAPA +OK CAPA TOP UIDL RESP-CODES PIPELINING STLS USER SASL PLAIN .

If your response does not include PLAIN then stop as you need a library that supports SPA

type: user myusername OR type: user myusername@domain.corp replacing domain.corp with your domain

You should then receive +OK

Type: pass mypass

You should get a response +OK

type: list

Should get a list of emails. This might help see if your issue is a username format issue.



回答5:

I wrote this to get email from my inbox. I have a tedious task to do every morning if an email is there, so I wrote this bit of code to check my folder for an email title. I added a small bit of xml creation to show the possibilities. Its not exchange but it works in my case. XCData encodes any special char in the body. I guess I should point out that email subject I'm looking for is [Ticket - Support#12345]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office;
using System.Xml.Linq;

namespace ProcessEmail
{
    class Program
    {
        static void Main(string[] args)
        {
            Outlook.Application outlook = new Outlook.Application();
            Outlook.NameSpace ns = outlook.GetNamespace("Mapi");
            object _missing = Type.Missing;
            ns.Logon(_missing, _missing, false, true);

            Outlook.MAPIFolder inbox = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

            int unread = inbox.UnReadItemCount;
            XElement xmlMail = new XElement("Mail");
            foreach (Outlook.MailItem mail in inbox.Items)
            {               
                string s = mail.Subject;

                if (s != null)
                {
                    if (s.Contains("Tickets") || (s.Contains("Support")))
                    {
                        string[] splitter = s.Split('#');
                        string[] split = splitter[1].Split(']');                       
                        string num = split[0].Trim();

                        XElement mailrow = new XElement("MailRow",
                            new XElement("Ticket_Number",num),
                            new XElement("Subject", mail.Subject),
                            new XElement("Body",  new XCData(mail.Body)),
                            new XElement("From", mail.SenderEmailAddress)
                            );
                        xmlMail.Add(mailrow);
                    }
                }

            }
            xmlMail.Save("E:\\mailxml.xml");


        }
    }
}

Matt



回答6:

You could use this library: http://www.dimastr.com/redemption/



回答7:

You need to use the Exchange SDK if POP3 is not enabled in the Exchange Server. Another options is to use WebDAV.



回答8:

Another option is to configure Exchange to enable IMAP4. There exist 3rd party IMAP4 libraries for .NET, e.g. rebex.



回答9:

You could use EWS (Exchange webservices) starting from Exchange 2007. They seem to be always installed and are better supported than Webdav.

You can just import the webservice from your Exchangeserver (Search for an asmx-file in the installation directory). You can download EML-files from your mails and do many more things!



回答10:

You can use Exchange Web Services (Exchange 2007 or 2010) or WebDav (Exchange up to 2007, 2010 does not support WebDAV), but the API and implementation might be a bit cumbersome if you want to do quick development.

I have used IndependentSoft's libraries for WebDav and Exchange Web Services successfully in the past, which provide a wrapper around the Exchange APIs and are much simpler to use. They handle parsing the message and MIME quite well too.



回答11:

  1. The currently preferred API (in Exchange 2013 and 2016) is EWS. It is purely HTTP based and can be accessed from any language, but there are .Net and Java specific libraries.

    You can use EWSEditor to play with the API.

  2. Extended MAPI. This is the native API used by Outlook. It ends up using the MSEMS Exchange MAPI provider, which can talk to Exchange using RPC (Exchange 2013 no longer supports it) or RPC-over-HTTP (Exchange 2007 or newer) or MAPI-over-HTTP (Exchange 2013 and newer).

    The API itself can only be accessed from unmanaged C++ or Delphi. You can also use Redemption (any language) - its RDO family of objects is an Extended MAPI wrapper. To use Extended MAPI, you need to install either Outlook or the standalone (Exchange) version of MAPI (on extended support, and it does not support Unicode PST and MSG files and cannot access Exchange 2016). Extended MAPI can be used in a service.

    You can play with the API using OutlookSpy or MFCMAPI.

  3. Outlook Object Model - not Exchange specific, but it allows access to all data available in Outlook on the machine where the code runs. Cannot be used in a service.

  4. Exchange Active Sync. Microsoft no longer invests any significant resources into this protocol.

  5. Outlook used to install CDO 1.21 library (it wraps Extended MAPI), but it had been deprecated by Microsoft and no longer receives any updates.

  6. There used to be a third-party .Net MAPI wrapper called MAPI33, but it is no longer being developed or supported.

  7. WebDAV - deprecated.

  8. Collaborative Data Objects for Exchange (CDOEX) - deprecated.

  9. Exchange OLE DB Provider (EXOLEDB) - deprecated.