Domanda

Ho bisogno della possibilità di monitorare e leggere la posta elettronica da una determinata cassetta postale su un MS Exchange Server (interno alla mia azienda). Devo anche essere in grado di leggere l'indirizzo e-mail, l'oggetto, il corpo del messaggio del mittente e scaricare un allegato, se presente.

Qual è il modo migliore per farlo usando C # (o Vb.net)?

È stato utile?

Soluzione

È un casino. MAPI o CDO tramite una DLL di interoperabilità .NET è ufficialmente non supportato da Microsoft - sembrerà funzionare bene, ma ci sono problemi con perdite di memoria a causa della loro diversa memoria Modelli. È possibile utilizzare CDOEX, ma funziona solo sul server Exchange stesso, non in remoto; inutili. Potresti interagire con Outlook, ma ora hai appena fatto una dipendenza da Outlook; eccessivo. Infine, potresti utilizzare Supporto WebDAV di Exchange 2003 , ma WebDAV è complicato, .NET ha uno scarso supporto integrato per esso e (per aggiungere un insulto al danno) Exchange 2007 cade quasi completamente supporto WebDAV.

Cosa deve fare un ragazzo? Ho finito per utilizzare Componente IMAP di AfterLogic per comunicare con il mio server Exchange 2003 tramite IMAP, e questo ha finito per funzionare molto bene. (Di solito cerco librerie gratuite o open-source, ma ho trovato tutte quelle che desideravano .NET, specialmente quando si tratta di alcune delle stranezze dell'implementazione IMAP del 2003 - e questa era abbastanza economica e ha funzionato sul primo prova. So che ce ne sono altri là fuori.)

Se la tua organizzazione è su Exchange 2007, tuttavia, sei fortunato. Exchange 2007 viene fornito con un'interfaccia di servizio Web basata su SOAP che infine fornisce un modo unificato e indipendente dalla lingua di interagire con il server Exchange. Se riesci a rendere 2007+ un requisito, questa è sicuramente la strada da percorrere. (Purtroppo per me, la mia azienda ha una politica "ma il 2003 non è rotto").

Se è necessario collegare entrambi Exchange 2003 e 2007, IMAP o POP3 è sicuramente la strada da percorrere.

Altri suggerimenti

Uhm,

Potrei essere un po 'troppo tardi qui, ma non è questo il punto di EWS?

https://msdn.microsoft.com/en -us / library / dd633710 (EXCHG.80) aspx

Prende circa 6 righe di codice per ottenere la posta da una cassetta postale:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

//service.Credentials = new NetworkCredential( "{Active Directory ID}", "{Password}", "{Domain Name}" );

service.AutodiscoverUrl( "First.Last@MyCompany.com" );

FindItemsResults<Item> findResults = service.FindItems(
   WellKnownFolderName.Inbox,
   new ItemView( 10 ) 
);

foreach ( Item item in findResults.Items )
{
   Console.WriteLine( item.Subject );
}
  1. L'API attualmente preferita (Exchange 2013 e 2016) è EWS . È basato esclusivamente su HTTP ed è possibile accedervi da qualsiasi lingua, ma esistono . Net e Java librerie specifiche.

    Puoi utilizzare EWSEditor per giocare con l'API.

  2. MAPI estesa . Questa è l'API nativa utilizzata da Outlook. Finisce con il provider MAPI di Exchange MSEMS , che può comunicare con Exchange utilizzando RPC (Exchange 2013 non lo supporta più) o RPC-over-HTTP (Exchange 2007 o più recente) o MAPI-over-HTTP (Exchange 2013 e successivi).

    L'API stessa è accessibile solo da C ++ non gestito o Delphi . Puoi anche utilizzare Redemption (qualsiasi lingua) - è RDO la famiglia di oggetti è un wrapper MAPI esteso. Per utilizzare Extended MAPI, devi installare Outlook o il standalone ( Exchange) versione di MAPI (su supporto esteso e non supporta file PST e MSG Unicode e non può accedere a Exchange 2016). MAPI estesa può essere utilizzata in un servizio.

    Puoi giocare con l'API usando OutlookSpy o MFCMAPI .

  3. Modello a oggetti di Outlook : non specifico di Exchange, ma consente l'accesso a tutti i dati disponibili in Outlook sul computer su cui viene eseguito il codice. Non può essere utilizzato in un servizio.

  4. Exchange Active Sync . Microsoft non investe più risorse significative in questo protocollo.

  5. Outlook usava installare la libreria CDO 1.21 (racchiude MAPI estesa), ma era stato deprecato da Microsoft e non riceve più alcun aggiornamento.

  6. C'era un wrapper .Net MAPI di terze parti chiamato MAPI33, ma non è più sviluppato o supportato.

  7. WebDAV - obsoleto.

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

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

Ecco un vecchio codice che avevo in giro per fare WebDAV. Penso che sia stato scritto contro Exchange 2003, ma non ricordo più. Sentiti libero di prenderlo in prestito se è utile ...

class MailUtil
{
    private CredentialCache creds = new CredentialCache();

    public MailUtil()
    {
        // set up webdav connection to exchange
        this.creds = new CredentialCache();
        this.creds.Add(new Uri("http://mail.domain.com/Exchange/me@domain.com/Inbox/"), "Basic", new NetworkCredential("myUserName", "myPassword", "WINDOWSDOMAIN"));
    }

    /// <summary>
    /// Gets all unread emails in a user's Inbox
    /// </summary>
    /// <returns>A list of unread mail messages</returns>
    public List<model.Mail> GetUnreadMail()
    {
        List<model.Mail> unreadMail = new List<model.Mail>();

        string reqStr =
            @"<?xml version=""1.0""?>
                <g:searchrequest xmlns:g=""DAV:"">
                    <g:sql>
                        SELECT
                            ""urn:schemas:mailheader:from"", ""urn:schemas:httpmail:textdescription""
                        FROM
                            ""http://mail.domain.com/Exchange/me@domain.com/Inbox/"" 
                        WHERE 
                            ""urn:schemas:httpmail:read"" = FALSE 
                            AND ""urn:schemas:httpmail:subject"" = 'tbintg' 
                            AND ""DAV:contentclass"" = 'urn:content-classes:message' 
                        </g:sql>
                </g:searchrequest>";

        byte[] reqBytes = Encoding.UTF8.GetBytes(reqStr);

        // set up web request
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://mail.domain.com/Exchange/me@domain.com/Inbox/");
        request.Credentials = this.creds;
        request.Method = "SEARCH";
        request.ContentLength = reqBytes.Length;
        request.ContentType = "text/xml";
        request.Timeout = 300000;

        using (Stream requestStream = request.GetRequestStream())
        {
            try
            {
                requestStream.Write(reqBytes, 0, reqBytes.Length);
            }
            catch
            {
            }
            finally
            {
                requestStream.Close();
            }
        }

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            try
            {
                XmlDocument document = new XmlDocument();
                document.Load(responseStream);

                // set up namespaces
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                nsmgr.AddNamespace("a", "DAV:");
                nsmgr.AddNamespace("b", "urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/");
                nsmgr.AddNamespace("c", "xml:");
                nsmgr.AddNamespace("d", "urn:schemas:mailheader:");
                nsmgr.AddNamespace("e", "urn:schemas:httpmail:");

                // Load each response (each mail item) into an object
                XmlNodeList responseNodes = document.GetElementsByTagName("a:response");
                foreach (XmlNode responseNode in responseNodes)
                {
                    // get the <propstat> node that contains valid HTTP responses
                    XmlNode uriNode = responseNode.SelectSingleNode("child::a:href", nsmgr);
                    XmlNode propstatNode = responseNode.SelectSingleNode("descendant::a:propstat[a:status='HTTP/1.1 200 OK']", nsmgr);
                    if (propstatNode != null)
                    {
                        // read properties of this response, and load into a data object
                        XmlNode fromNode = propstatNode.SelectSingleNode("descendant::d:from", nsmgr);
                        XmlNode descNode = propstatNode.SelectSingleNode("descendant::e:textdescription", nsmgr);

                        // make new data object
                        model.Mail mail = new model.Mail();
                        if (uriNode != null)
                            mail.Uri = uriNode.InnerText;
                        if (fromNode != null)
                            mail.From = fromNode.InnerText;
                        if (descNode != null)
                            mail.Body = descNode.InnerText;
                        unreadMail.Add(mail);
                    }
                }

            }
            catch (Exception e)
            {
                string msg = e.Message;
            }
            finally
            {
                responseStream.Close();
            }
        }

        return unreadMail;
    }
}

E model.Mail:

class Mail
{
    private string uri;
    private string from;
    private string body;

    public string Uri
    {
        get { return this.uri; }
        set { this.uri = value; }
    }

    public string From
    {
        get { return this.from; }
        set { this.from = value; }
    }

    public string Body
    {
        get { return this.body; }
        set { this.body = value; }
    }
}

Ho usato il codice che era pubblicato su CodeProject.com . Se vuoi usare POP3, è una delle migliori soluzioni che ho trovato.

Se il tuo server Exchange è configurato per supportare POP o IMAP, è una soluzione semplice.

Un'altra opzione è l'accesso WebDAV. esiste una libreria disponibile per questo. Questa potrebbe essere la tua migliore opzione.

Penso che ci siano opzioni che usano oggetti COM per accedere a Exchange, ma non sono sicuro di quanto sia facile.

Tutto dipende da cosa esattamente il tuo amministratore è disposto a darti accesso a suppongo.

Dovresti essere in grado di utilizzare MAPI per accedere alla cassetta postale e ottenere le informazioni di cui hai bisogno. Sfortunatamente l'unica libreria .NET MAPI (MAPI33) che conosco sembra non essere mantenuta. Questo era un ottimo modo per accedere a MAPI tramite .NET, ma non posso parlare ora della sua efficacia. Sono disponibili ulteriori informazioni su dove è possibile ottenerlo qui: Percorso di download per MAPI33.dll?

Alla fine ho trovato una soluzione che utilizza Redemption, dai un'occhiata a queste domande ...

Un'opzione è usare Outlook. Abbiamo un'applicazione di gestione della posta che accede a un server di scambio e utilizza Outlook come interfaccia. È sporco ma funziona.

Codice di esempio:

public Outlook.MAPIFolder getInbox()
        {
            mailSession = new Outlook.Application();
            mailNamespace = mailSession.GetNamespace("MAPI");
            mailNamespace.Logon(mail_username, mail_password, false, true);
            return MailNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
        }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top