Saya memerlukan kemampuan untuk memantau dan membaca email dari kotak surat tertentu di MS Exchange Server (internal perusahaan saya). Saya juga harus bisa membaca alamat email pengirim, subjek, isi pesan dan mendownload lampiran, jika ada.
Apa cara terbaik untuk melakukan ini menggunakan C # (atau VB.NET)?
c#
email
exchange-server
mapi
vajarov.dll
sumber
sumber
Jawaban:
Ini berantakan. MAPI atau CDO melalui .NET interop DLL secara resmi tidak didukung oleh Microsoft - tampaknya akan berfungsi dengan baik, namun ada masalah dengan kebocoran memori karena model memorinya yang berbeda. Anda dapat menggunakan CDOEX, tetapi itu hanya berfungsi di server Exchange itu sendiri, tidak dari jarak jauh; tak berguna. Anda dapat melakukan interop dengan Outlook, tetapi sekarang Anda baru saja membuat ketergantungan pada Outlook; berlebihan. Terakhir, Anda dapat menggunakan dukungan WebDAV Exchange 2003 , tetapi WebDAV rumit, .NET memiliki dukungan bawaan yang buruk untuk itu, dan (untuk menambah penghinaan terhadap cedera) Exchange 2007 hampir sepenuhnya menjatuhkan dukungan WebDAV.
Apa yang harus dilakukan pria? Saya akhirnya menggunakan komponen IMAP AfterLogic untuk berkomunikasi dengan server Exchange 2003 saya melalui IMAP, dan ini akhirnya bekerja dengan sangat baik. (Saya biasanya mencari pustaka gratis atau sumber terbuka, tetapi saya menemukan semua yang .NET inginkan - terutama bila menyangkut beberapa kebiasaan implementasi IMAP tahun 2003 - dan yang satu ini cukup murah dan bekerja pada yang pertama. coba. Saya tahu ada orang lain di luar sana.)
Namun, jika organisasi Anda ada di Exchange 2007, Anda beruntung. Exchange 2007 hadir dengan antarmuka layanan Web berbasis SOAP yang akhirnya menyediakan cara bahasa-bahasa yang terpadu untuk berinteraksi dengan server Exchange. Jika Anda dapat menjadikan 2007+ sebagai persyaratan, ini pasti cara yang tepat. (Sayangnya bagi saya, perusahaan saya memiliki kebijakan "tetapi 2003 tidak rusak".)
Jika Anda perlu menjembatani Exchange 2003 dan 2007, IMAP atau POP3 jelas merupakan cara yang tepat.
sumber
Um,
Saya mungkin agak terlambat di sini, tetapi bukankah ini maksudnya EWS?
https://msdn.microsoft.com/en-us/library/dd633710(EXCHG.80).aspx
Butuh sekitar 6 baris kode untuk mengambil email dari kotak surat:
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 ); }
sumber
service.autodiscoverurl
, saya harus memasukkanservice.credentials
, apakah saya benar?API (Exchange 2013 dan 2016) yang saat ini disukai adalah EWS . Ini murni berbasis HTTP dan dapat diakses dari bahasa apa pun, tetapi ada pustaka khusus .Net dan Java .
Anda dapat menggunakan EWSEditor untuk bermain dengan API.
MAPI diperpanjang . Ini adalah API asli yang digunakan oleh Outlook. Ini akhirnya menggunakan
MSEMS
penyedia Exchange MAPI, yang dapat berbicara dengan Exchange menggunakan RPC (Exchange 2013 tidak lagi mendukungnya) atau RPC-over-HTTP (Exchange 2007 atau yang lebih baru) atau MAPI-over-HTTP (Exchange 2013 dan yang lebih baru).API itu sendiri hanya dapat diakses dari C ++ atau Delphi yang tidak dikelola . Anda juga dapat menggunakan Penukaran (bahasa apa pun) - kelompok objek RDO -nya adalah pembungkus MAPI yang Diperluas. Untuk menggunakan Extended MAPI, Anda perlu menginstal Outlook atau versi mandiri (Exchange) MAPI (pada dukungan diperpanjang, dan tidak mendukung file Unicode PST dan MSG dan tidak dapat mengakses Exchange 2016). MAPI yang diperluas dapat digunakan dalam layanan.
Anda dapat bermain dengan API menggunakan OutlookSpy atau MFCMAPI .
Model Objek Outlook - tidak khusus Exchange, tetapi memungkinkan akses ke semua data yang tersedia di Outlook pada mesin tempat kode dijalankan. Tidak dapat digunakan dalam layanan.
Exchange Active Sync . Microsoft tidak lagi menginvestasikan sumber daya yang signifikan ke dalam protokol ini.
Outlook digunakan untuk menginstal pustaka CDO 1.21 (ini membungkus MAPI yang Diperluas), tetapi sudah usang oleh Microsoft dan tidak lagi menerima pembaruan apa pun.
Dulu ada pembungkus MAPI .Net pihak ketiga yang disebut MAPI33, tetapi tidak lagi dikembangkan atau didukung.
WebDAV - tidak digunakan lagi.
Objek Data Kolaboratif untuk Exchange (CDOEX) - tidak digunakan lagi.
Exchange OLE DB Provider (EXOLEDB) - tidak digunakan lagi.
sumber
Berikut adalah beberapa kode lama yang telah saya berikan untuk melakukan WebDAV. Saya pikir itu ditulis melawan Exchange 2003, tapi saya tidak ingat lagi. Jangan ragu untuk meminjamnya jika membantu ...
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; } }
Dan 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; } } }
sumber
Saya menggunakan kode yang diterbitkan di CodeProject.com . Jika Anda ingin menggunakan POP3, ini adalah salah satu solusi terbaik yang saya temukan.
sumber
Jika server Exchange Anda dikonfigurasi untuk mendukung POP atau IMAP, itu jalan keluar yang mudah.
Pilihan lainnya adalah akses WebDAV. ada perpustakaan yang tersedia untuk itu. Ini mungkin pilihan terbaik Anda.
Saya pikir ada opsi menggunakan objek COM untuk mengakses Exchange, tapi saya tidak yakin betapa mudahnya itu.
Itu semua tergantung pada apa yang sebenarnya ingin diberikan administrator Anda kepada Anda.
sumber
Anda harus dapat menggunakan MAPI untuk mengakses kotak surat dan mendapatkan informasi yang Anda butuhkan. Sayangnya satu-satunya pustaka .NET MAPI (MAPI33) yang saya ketahui tampaknya tidak terawat. Ini dulunya adalah cara terbaik untuk mengakses MAPI melalui .NET, tetapi saya tidak dapat menjelaskan keefektifannya sekarang. Ada informasi lebih lanjut tentang di mana Anda bisa mendapatkannya di sini: Unduh lokasi untuk MAPI33.dll?
sumber
Saya mendapat solusi yang berfungsi pada akhirnya menggunakan Penebusan, lihat pertanyaan-pertanyaan ini ...
Menggunakan Penebusan ...
Menggunakan Penukaran di mesin 64 bit
sumber
Salah satu opsinya adalah menggunakan Outlook. Kami memiliki aplikasi pengelola email yang mengakses server pertukaran dan menggunakan pandangan sebagai antarmuka. Ini kotor tapi berhasil.
Kode contoh:
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); }
sumber