c # отправка почты с помощью smtp через exchange 2K7 - PullRequest
1 голос
/ 14 ноября 2011

следующий код работает при отправке через smtp gmail, но не через exchange 2K7. на той же машине у меня есть Outlook Express, который успешно отправляет через обмен. Я использую те же настройки в моем коде, что и в Outlook Express, но получаю сообщение об ошибке:

The SMTP server requires a secure connection or the client was not authenticated.
The server response was: 5.7.1 Client was not authenticated.
Stack:    at System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response)
   at System.Net.Mail.MailCommand.Send ...

Ssl имеет значение true.

вот код:

//create new MailMessage
mailmessage = new MailMessage(definition.From, definition.To);
mailmessage.ReplyToList.Add(definition.From);
mailmessage.IsBodyHtml = true;
mailmessage.SubjectEncoding = System.Text.Encoding.UTF8;
mailmessage.BodyEncoding = System.Text.Encoding.UTF8;
mailmessage.Subject = definition.Subject;
mailmessage.Body = definition.Body;

mailmessage = MessageBody.CompleteMessage(mailmessage, definition);

//send MailMessage
//get smtpclient
SmtpClient smtp = null;

if (smtp == null)
{
//create, init
smtp = new SmtpClient(definition.Server, definition.Port)
{
    Credentials = new NetworkCredential(definition.Uid, definition.Pwd),
    EnableSsl = definition.Ssl,
    DeliveryMethod = SmtpDeliveryMethod.Network
};

}
ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
smtp.Send(mailmessage);

ОБНОВЛЕНИЕ: когда я вынимаю строку обратного вызова и пытаюсь отправить, я получаю эту ошибку:

Exception: The remote certificate is invalid according to the validation procedure.. Stack:    at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.TlsStream.CallProcessAuthentication(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Mail.SmtpConnection.Flush()
   at System.Net.Mail.ReadLinesCommand.Send(SmtpConnection conn)
   at System.Net.Mail.EHelloCommand.Send(SmtpConnection conn, String domain)
   at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)
   at System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint)
   at System.Net.Mail.SmtpClient.GetConnection()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)

Ответы [ 2 ]

3 голосов
/ 15 ноября 2011

нашел хорошее решение.не пытайтесь использовать SMTP с обменом 2K7 и выше.вместо этого используйте EWS (веб-службы Exchange).

:

  1. загрузить управляемый API EWS из http://www.microsoft.com/download/en/details.aspx?id=13480
  2. Установить его
  3. Добавьте ссылку на Microsoft.Exchange.WebServices.dll в ваш проект.вы найдете его в C: \ Program Files (x86) \ Microsoft \ Exchange \ Web Services \ 1.1
  4. Используйте приведенный ниже пример кода для справки.

    с использованием Microsoft.Exchange.WebServices.Data;

    с использованием System.Security.Cryptography.X509Certificates;

...

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

service.Url = new Uri(@"https://"+[Your exchange computer name like: abc.domain.com]+"/EWS/Exchange.asmx"); 

//if have the ip you can get the computer name using the nslookup utility in command line. ->nslookup 192.168.0.90 

ServicePointManager.ServerCertificateValidationCallback =
                    delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                    {
                        return true;
                    };

service.Credentials = new WebCredentials([User name: either email or domain account-but without the domain\], "password");

EmailMessage mailmessage = new EmailMessage(service);

mailmessage.From="me@something.com";

mailmessage.ToRecipients.Add("someone@something.com");

mailmessage.Subject = "Hello";

mailmessage.Body = "World";

mailmessage.Body.BodyType = BodyType.HTML; //or text

mailmessage.Send();

надеюсь, что это поможет вам.

1 голос
/ 14 ноября 2011

С манжеты, похоже, вы все делаете правильно. У меня есть два предположения: это удары в темноте, но вы, возможно, захотите взглянуть поближе:

Поскольку вы получаете: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated. Stack: at System.Net.Mail.MailCommand ... Мне придется предположить, что у сервера Exchange возникла проблема при интерпретации пакета, который он получает.

1) Это может быть связано с шифрованием SSL. Я бы перепроверил, что вам нужен SSL. Вы можете отправить (хотя это и не рекомендуется) имя пользователя и пароль без SSL. Это было бы плохой настройкой сервера, но это, вероятно, вне вашего контроля.

2) Вы также выполняете обратный вызов для проверки сертификата. Это дополнительный уровень проверки SMTP, который может конфликтовать с пакетом SSL. Вы можете отправить письмо без этой строки?

Надеюсь, это может подтолкнуть вас к ИСТИННОМУ ответу.

...