Чтение электронной почты MS Exchange в С#
Мне нужна возможность отслеживать и читать электронную почту из определенного почтового ящика на сервере MS Exchange (внутреннем для моей компании). Мне также нужно иметь возможность прочитать адрес электронной почты отправителя, тему, текст сообщения и загрузить вложение, если оно есть.
Каков наилучший способ сделать это с помощью С# (или VB.NET)?
Ответы
Ответ 1
Это беспорядок. MAPI или CDO через DLL-библиотеку .NET. официально не поддерживается Microsoft - это будет работать нормально, но есть проблемы с утечками памяти из-за к их разным моделям памяти. Вы можете использовать CDOEX, но это работает только на сервере Exchange, а не удаленно; бесполезный. Вы могли бы взаимодействовать с Outlook, но теперь вы только что сделали зависимость от Outlook; излишество. Наконец, вы можете использовать поддержку Exchange 2003 WebDAV, но WebDAV сложна,.NET имеет плохую встроенную поддержку для нее и (чтобы добавить оскорбление к травме) Exchange 2007 почти полностью снижает поддержку WebDAV.
Какой парень? Я закончил использование компонента AfterLogic IMAP для связи с моим сервером Exchange 2003 через IMAP, и это в конечном итоге работало очень хорошо. (Обычно я ищу бесплатные библиотеки с открытым исходным кодом, но я нашел, что все .NET хотят - особенно когда дело доходит до некоторых причуд внедрения IMAP 2003 года, - и этот был достаточно дешев и работал на первом Я знаю, что есть другие.)
Если ваша организация находится на Exchange 2007, вам повезло. Exchange 2007 поставляется с SOAP-интерфейсом веб-сервисов, который, наконец, обеспечивает унифицированный, независимый от языка способ взаимодействия с сервером Exchange. Если вы можете сделать требование 2007+, это определенно путь. (К сожалению, у меня в моей компании политика "но не в 2003 году" ).
Если вам необходимо сменить оба Exchange 2003 и 2007, IMAP или POP3, безусловно, путь.
Ответ 2
Хм,
Может быть, я немного опоздал, но разве не в этом смысл 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( "[email protected]" );
FindItemsResults<Item> findResults = service.FindItems(
WellKnownFolderName.Inbox,
new ItemView( 10 )
);
foreach ( Item item in findResults.Items )
{
Console.WriteLine( item.Subject );
}
Ответ 3
-
В настоящее время предпочтительным (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 является оболочкой Extended 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) - устарело.
-
Поставщик OLE DB для Exchange (EXOLEDB) - устарел.
Ответ 4
Вот какой-то старый код, который я использовал для создания 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/[email protected]/Inbox/"), "Basic", new NetworkCredential("myUserName", "myPassword", "WINDOWSDOMAIN"));
}
/// <summary>
/// Gets all unread emails in a user 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;
}
}
И 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; }
}
}
Ответ 5
Я использовал код опубликованный на CodeProject.com. Если вы хотите использовать POP3, это одно из лучших решений, которые я нашел.
Ответ 6
Если ваш сервер Exchange настроен на поддержку POP или IMAP, это простой выход.
Другой вариант - доступ к WebDAV. для этого доступно библиотека. Это может быть вашим лучшим вариантом.
Я думаю, что есть опции, использующие COM-объекты для доступа к Exchange, но я не уверен, насколько это просто.
Все зависит от того, что именно ваш администратор готов предоставить вам доступ, я думаю.
Ответ 7
Вы должны иметь возможность использовать MAPI для доступа к почтовому ящику и получения необходимой вам информации. К сожалению, единственная библиотека .NET MAPI (MAPI33), которую я знаю, кажется, не поддерживается. Это был отличный способ получить доступ к MAPI через .NET, но теперь я не могу говорить о его эффективности. Там больше информации о том, где вы можете получить его здесь: Загрузить местоположение для MAPI33.dll?
Ответ 8
У меня есть решение, работающее в конце с использованием Redemption, взгляните на эти вопросы...
Ответ 9
Один из вариантов - использовать 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);
}
Ответ 10
Я думаю, что лучше использовать EWS.. следуйте этой ссылке - MSDN-EWS