Вопрос

Мне нужна возможность отслеживать и читать электронную почту из определенного почтового ящика на сервере MS Exchange (внутреннем для моей компании).Мне также нужно иметь возможность прочитать адрес электронной почты отправителя, тему, текст сообщения и загрузить вложение, если таковое имеется.

Каков наилучший способ сделать это с помощью C # (или Vb.net)?

Это было полезно?

Решение

Это беспорядок. MAPI или CDO через .NET Interop DLL является , официально не поддерживаемый Microsoft - он будет работать нормально, но есть проблемы с утечками памяти из-за различий в памяти моделей. Вы можете использовать CDOEX, но это работает только на самом сервере Exchange, а не удаленно; бесполезный. Вы можете взаимодействовать с Outlook, но теперь вы только что сделали зависимость от Outlook; излишество. Наконец, вы можете использовать поддержку Exchange 2003 в WebDAV , но WebDAV сложен, .NET имеет слабую встроенную поддержку для этого, и (для оскорбления травмы) Exchange 2007 почти полностью прекращает поддержку WebDAV.

Что делать парню? В итоге я использовал компонент IMAP AfterLogic для связи с сервером Exchange 2003 через IMAP, и это в конечном итоге работает очень хорошо. (Обычно я ищу бесплатные библиотеки или библиотеки с открытым исходным кодом, но я обнаружил, что все .NET хотят, особенно когда речь идет о некоторых особенностях реализации IMAP 2003 года - и эта была достаточно дешевой и работала над первым попробуй. Я знаю, что есть и другие.)

Однако если ваша организация работает на Exchange 2007, вам повезло. Exchange 2007 поставляется с интерфейсом веб-службы на основе SOAP , который, наконец, обеспечивает унифицированный, независимый от языка способ взаимодействия с сервером Exchange. Если вы можете сделать 2007+ обязательным требованием, это определенно верный путь. (К сожалению, для моей компании есть & Квота; но 2003 год не нарушен & Quot; policy.)

Если вам нужно соединить и Exchange 2003, и 2007, IMAP или POP3 определенно помогут.

Другие советы

Гм,

Может быть, я немного опоздал, но разве не в этом смысл EWS?

https://msdn.microsoft.com/en -us / библиотека / 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 );
}
<Ол>
  • В настоящее время предпочтительным (Exchange 2013 и 2016) API является EWS . Он основан исключительно на HTTP и может быть доступен с любого языка, но есть . Сетевые и 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 . Вы также можете использовать погашение (любой язык) - его 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 (она содержит Extended MAPI), но Microsoft устарела и больше не получает обновлений.

  • Раньше была сторонняя оболочка .Net MAPI под названием MAPI33, но она больше не разрабатывается и не поддерживается.

  • WebDAV - устарело.

  • Совместные объекты данных для Exchange (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, взгляните на эти вопросы...

    Один из вариантов - использовать Outlook. У нас есть приложение для работы с почтовым менеджером, которое обращается к серверу Exchange и использует 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);
            }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top