Lee el correo electrónico de MS Exchange en C #

Necesito la capacidad de supervisar y leer correos electrónicos desde un buzón particular en un servidor de MS Exchange (interno de mi empresa). También necesito poder leer la dirección de correo electrónico del remitente, el asunto, el cuerpo del mensaje y descargar un archivo adjunto, si corresponde.

¿Cuál es la mejor manera de hacer esto usando C # (o Vb.net)?

Es un desastre. MAP / CDO a través de una DLL de interconexión .NET oficialmente no está soportado por Microsoft. Aparentemente funcionará bien, pero existen problemas con las pérdidas de memoria debido a sus diferentes modelos de memoria. Puede usar CDOEX, pero eso solo funciona en el servidor de Exchange, no de forma remota; inútil. Podría interoperar con Outlook, pero ahora acaba de hacer una dependencia en Outlook; excesivo Finalmente, puede usar la compatibilidad con WebDAV de Exchange 2003 , pero WebDAV es complicado, .NET tiene un soporte integrado deficiente para él y, para colmo de males, Exchange 2007 casi elimina completamente el soporte de WebDAV.

¿Qué es un chico que hacer? Terminé usando el componente IMAP de AfterLogic para comunicarme con mi servidor de Exchange 2003 a través de IMAP, y esto terminó funcionando muy bien. (Normalmente busco bibliotecas gratuitas o de código abierto, pero encontré que faltaban todas las .NET, especialmente cuando se trata de algunas de las peculiaridades de la implementación de IMAP en 2003, y esta era bastante barata y funcionó en la primera bash. Sé que hay otros por ahí).

Sin embargo, si su organización está en Exchange 2007, tiene suerte. Exchange 2007 viene con una interfaz de servicio web basada en SOAP que finalmente proporciona una forma unificada, independiente del lenguaje, de interactuar con el servidor de Exchange. Si puede hacer 2007+ un requisito, este es definitivamente el camino a seguir. (Tristemente para mí, mi empresa tiene una política de “pero 2003 no está roto”).

Si necesita unir tanto Exchange 2003 como 2007, IMAP o POP3 es definitivamente el camino a seguir.

Um,

Podría ser un poco tarde aquí, pero ¿no es este el tema de EWS?

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

Toma aproximadamente 6 líneas de código para obtener el correo de un buzón:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1); //service.Credentials = new NetworkCredential( "{Active Directory ID}", "{Password}", "{Domain Name}" ); service.AutodiscoverUrl( "Fi[email protected]" ); FindItemsResults findResults = service.FindItems( WellKnownFolderName.Inbox, new ItemView( 10 ) ); foreach ( Item item in findResults.Items ) { Console.WriteLine( item.Subject ); } 
  1. La API actualmente preferida (Exchange 2013 y 2016) es EWS . Está basado exclusivamente en HTTP y se puede acceder desde cualquier idioma, pero hay bibliotecas específicas de .NET y Java .

    Puede usar EWSEditor para jugar con la API.

  2. MAPI extendido Esta es la API nativa utilizada por Outlook. Termina utilizando el proveedor MSEMS Exchange MAPI, que puede hablar con Exchange utilizando RPC (Exchange 2013 ya no lo admite) o RPC-over-HTTP (Exchange 2007 o posterior) o MAPI-over-HTTP (Exchange 2013 y posteriores).

    La API en sí misma solo se puede acceder desde C ++ no administrado o Delphi . También puede usar Redención (cualquier idioma): su familia de objetos RDO es un contenedor extendido de MAPI. Para utilizar MAPI extendido, debe instalar Outlook o la versión independiente (Exchange) de MAPI (en soporte extendido, y no admite archivos Unicode PST y MSG y no puede acceder a Exchange 2016). MAPI extendido se puede usar en un servicio.

    Puedes jugar con la API usando OutlookSpy o MFCMAPI .

  3. Modelo de objetos de Outlook : no específico de Exchange, pero permite el acceso a todos los datos disponibles en Outlook en la máquina donde se ejecuta el código. No se puede usar en un servicio.

  4. Exchange Active Sync . Microsoft ya no invierte recursos significativos en este protocolo.

  5. Outlook solía instalar la biblioteca CDO 1.21 (ajusta MAPI extendido), pero Microsoft la dejó de usar y ya no recibe ninguna actualización.

  6. Solía ​​haber un contenedor .NET MAPI de terceros llamado MAPI33, pero ya no se está desarrollando ni admitiendo.

  7. WebDAV: obsoleto.

  8. Objetos de datos colaborativos para Exchange (CDOEX): obsoleto.

  9. Proveedor OLE DB de Exchange (EXOLEDB): obsoleto.

Aquí hay un viejo código que tenía para hacer WebDAV. Creo que fue escrito contra Exchange 2003, pero no recuerdo más. Siéntase libre de pedir prestado si es útil …

 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/[email protected]/Inbox/"), "Basic", new NetworkCredential("myUserName", "myPassword", "WINDOWSDOMAIN")); } ///  /// Gets all unread emails in a user's Inbox ///  /// A list of unread mail messages public List GetUnreadMail() { List unreadMail = new List(); string reqStr = @"   SELECT ""urn:schemas:mailheader:from"", ""urn:schemas:httpmail:textdescription"" FROM ""http://mail.domain.com/Exchange/[email protected]/Inbox/"" WHERE ""urn:schemas:httpmail:read"" = FALSE AND ""urn:schemas:httpmail:subject"" = 'tbintg' AND ""DAV:contentclass"" = 'urn:content-classes:message'  "; byte[] reqBytes = Encoding.UTF8.GetBytes(reqStr); // set up web request HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://mail.domain.com/Exchange/[email protected]/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  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; } } 

Y modelo.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; } } } 

Usé el código que se publicó en CodeProject.com . Si desea utilizar POP3, es una de las mejores soluciones que he encontrado.

Si su servidor de Exchange está configurado para admitir POP o IMAP, esa es una salida fácil.

Otra opción es el acceso WebDAV. hay una biblioteca disponible para eso. Esta podría ser tu mejor opción.

Creo que hay opciones para usar objetos COM para acceder a Exchange, pero no estoy seguro de lo fácil que es.

Todo depende de a qué exactamente su administrador esté dispuesto a darle acceso, supongo.

Debería poder utilizar MAPI para acceder al buzón y obtener la información que necesita. Lamentablemente, la única biblioteca .NET MAPI (MAPI33) que conozco parece no estar en buen estado. Esta solía ser una gran manera de acceder a MAPI a través de .NET, pero no puedo hablar de su efectividad ahora. Hay más información sobre dónde puede obtenerlo aquí: ¿ Ubicación de descarga para MAPI33.dll?

Al final obtuve una solución que funciona al usar Redemption, eche un vistazo a estas preguntas …

  • Usando redención …

  • Uso de redención en una máquina de 64 bits

Una opción es usar Outlook. Tenemos una aplicación de administrador de correo que accede a un servidor de intercambio y usa Outlook como interfaz. Está sucio pero funciona.

Código de ejemplo:

 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); } 

Creo que es mejor usar EWS … siga este enlace: MSDN-EWS