Мне нужна возможность отслеживать и читать электронную почту из определенного почтового ящика на сервере MS Exchange (внутреннем для моей компании). Мне также необходимо иметь возможность читать адрес электронной почты отправителя, тему, текст сообщения и загружать вложения, если они есть.
Как лучше всего это сделать с помощью C # (или VB.NET)?
c#
email
exchange-server
mapi
Ваджаров
источник
источник
Ответы:
Это беспорядок. MAPI или CDO через .NET interop DLL официально не поддерживаются Microsoft - он будет работать нормально, но есть проблемы с утечками памяти из-за различных моделей памяти. Вы можете использовать CDOEX, но он работает только на самом сервере Exchange, а не удаленно; бесполезный. Вы могли взаимодействовать с Outlook, но теперь вы только что сделали зависимость от Outlook; перебор. Наконец, вы можете использовать поддержку WebDAV в Exchange 2003 , но WebDAV сложен, .NET имеет слабую встроенную поддержку для него, и (чтобы добавить оскорбления) Exchange 2007 почти полностью отказывается от поддержки WebDAV.
Что делать парню? В итоге я использовал компонент IMAP AfterLogic для связи с моим сервером Exchange 2003 через IMAP, и это в итоге работало очень хорошо. (Обычно я ищу бесплатные библиотеки или библиотеки с открытым исходным кодом, но я обнаружил, что все .NET-библиотеки нужны - особенно когда дело доходит до некоторых причуд реализации IMAP 2003 года - и эта была достаточно дешевой и работала над первым попробуй. Я знаю, что есть и другие.)
Однако если ваша организация использует Exchange 2007, вам повезло. Exchange 2007 поставляется с интерфейсом веб-службы на основе SOAP, который наконец обеспечивает унифицированный, независимый от языка способ взаимодействия с сервером Exchange. Если вы можете сделать 2007+ обязательным, это определенно правильный путь. (К сожалению для меня, моя компания придерживается политики «но 2003 год не нарушен».)
Если вам нужно соединить как Exchange 2003, так и 2007, IMAP или POP3 определенно лучший вариант.
источник
Гм,
Возможно, я здесь слишком поздно, но разве не в этом смысл EWS?
https://msdn.microsoft.com/en-us/library/dd633710(EXCHG.80).aspx
Для получения почты из почтового ящика требуется около 6 строк кода:
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 ); }
источник
service.autodiscoverurl
, мне нужно было бы ввестиservice.credentials
, правильно?В настоящее время предпочтительным (Exchange 2013 и 2016) API является EWS . Он основан исключительно на HTTP и может быть доступен с любого языка, но существуют специальные библиотеки .Net и Java .
Вы можете использовать EWSEditor для игры с API.
Расширенный MAPI . Это собственный API, используемый Outlook. В конечном итоге он использует
MSEMS
поставщика Exchange MAPI, который может взаимодействовать с Exchange с помощью RPC (Exchange 2013 больше не поддерживает его), RPC-over-HTTP (Exchange 2007 или новее) или MAPI-over-HTTP (Exchange 2013 и новее).К самому API можно получить доступ только из неуправляемого C ++ или Delphi . Вы также можете использовать Redemption (любой язык) - его семейство объектов RDO является расширенной оболочкой MAPI. Чтобы использовать расширенный MAPI, вам необходимо установить Outlook или автономную (Exchange) версию MAPI (с расширенной поддержкой, она не поддерживает файлы Unicode PST и MSG и не может получить доступ к Exchange 2016). Расширенный MAPI можно использовать в службе.
Вы можете играть с API, используя OutlookSpy или MFCMAPI .
Объектная модель Outlook - не только для Exchange, но позволяет получить доступ ко всем данным, доступным в Outlook на компьютере, на котором выполняется код. Не может использоваться в службе.
Exchange Active Sync . Microsoft больше не вкладывает значительные ресурсы в этот протокол.
Outlook использовался для установки библиотеки CDO 1.21 (она включает расширенный MAPI), но она устарела Microsoft и больше не получает никаких обновлений.
Раньше существовала сторонняя оболочка .Net MAPI под названием MAPI33, но она больше не разрабатывается и не поддерживается.
WebDAV - не рекомендуется.
Совместные объекты данных для обмена (CDOEX) - устарело.
Exchange OLE DB Provider (EXOLEDB) - не рекомендуется.
источник
Вот какой-то старый код, который у меня был для работы с WebDAV. Я думаю, это было написано против Exchange 2003, но больше не помню. Не стесняйтесь брать его, если он поможет ...
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; } }
И модель. Почта:
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; } } }
источник
Я использовал код, опубликованный на CodeProject.com . Если вы хотите использовать POP3, это одно из лучших решений, которые я нашел.
источник
Если ваш сервер Exchange настроен для поддержки POP или IMAP, это простой выход.
Другой вариант - доступ по WebDAV. для этого есть библиотека . Это может быть вашим лучшим вариантом.
Я думаю, что есть варианты использования COM-объектов для доступа к Exchange, но я не уверен, насколько это просто.
Все зависит от того, к чему именно ваш администратор готов предоставить вам доступ, я думаю.
источник
Вы должны иметь возможность использовать MAPI для доступа к почтовому ящику и получения необходимой информации. К сожалению, единственная известная мне библиотека .NET MAPI (MAPI33), похоже, не обслуживается. Раньше это был отличный способ доступа к MAPI через .NET, но сейчас я не могу говорить об его эффективности. Дополнительную информацию о том, где это можно получить, можно найти здесь: Местоположение для загрузки MAPI33.dll?
источник
У меня есть решение, работающее в итоге с использованием Redemption, посмотрите эти вопросы ...
Использование выкупа ...
Использование Redemption на 64-битной машине
источник
Один из вариантов - использовать Outlook. У нас есть приложение почтового менеджера, которое обращается к серверу обмена и использует Outlook в качестве интерфейса. Это грязно, но работает.
Пример кода:
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); }
источник