regular - Lee el correo electrónico de MS Exchange en C#
leer correo outlook desde c# (10)
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)?
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.
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 Redemption (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.
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.
Exchange Active Sync . Microsoft ya no invierte recursos significativos en este protocolo.
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.
Solía haber un contenedor .NET MAPI de terceros llamado MAPI33, pero ya no se está desarrollando ni admitiendo.
WebDAV: obsoleto.
Objetos de datos colaborativos para Exchange (CDOEX): obsoleto.
Proveedor OLE DB de Exchange (EXOLEDB): obsoleto.
Al final obtuve una solución que funciona al usar Redemption, eche un vistazo a estas preguntas ...
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"));
}
/// <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/[email protected]/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/[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 <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;
}
}
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; }
}
}
Creo que es mejor usar EWS ... siga este enlace: https://msdn.microsoft.com/en-us/library/dd633710(EXCHG.80).aspx
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?
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 intento. 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.
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 library 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.
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( "[email protected]" );
FindItemsResults<Item> findResults = service.FindItems(
WellKnownFolderName.Inbox,
new ItemView( 10 ) );
foreach ( Item item in findResults.Items )
{
Console.WriteLine( item.Subject );
}
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);
}
Usé el código que se publicó en CodeProject.com . Si desea utilizar POP3, es una de las mejores soluciones que he encontrado.