当两者使用相同的SMTP服务器时,为什么MailMessage从Windows窗体应用程序发送到任何地址,而不是从ASP.NET应用程序发送到?

时间:2010-01-27 08:38:22

标签: .net asp.net smtp winforms smtpclient

从ASP.NET Web应用程序通过SMTP服务器发送电子邮件时,我遇到了一个神秘的(对我而言)错误。我得到了着名的错误“无法接收xxx@yyy.zzz”。对我来说神秘的是,当我剪切并粘贴将电子邮件发送到通常的.NET Windows Forms应用程序的完全相同的代码时,使用此应用程序发送电子邮件,一切正常。这让我觉得问题可能是ASP.NET应用程序运行为NETWORK SERVICE而Windows Forms应用程序在域用户帐户上运行,但事实证明我有另一个ASP.NET应用程序通过它发送电子邮件在同一IIS的NETWORK SERVER下运行的SMTP服务器,此应用程序不会遇到此问题。

我进一步尝试通过端口25上的SMTP服务器telnet手动通过SMTP服务器发送电子邮件,并手动运行SMTP协议,一切正常。 SMTP服务器未配置任何类型的身份验证或SSL。

另一个神秘的事实是,ASP.NET应用程序可以将同一域内地址的电子邮件发送到同一域内的电子邮件地址,但不能发送到域外的任何地址。但是,使用完全相同的代码的Windows窗体应用程序可以从任何地址向域内外的任何地址发送电子邮件。

总结一下:

  • ASP.NET应用程序可以发送 来自地址内的电子邮件 域到域内的地址, 但不是外面的地址 域。
  • 正在运行的Windows窗体应用程序 同一台计算机上的相同代码 可以从任何地址发送电子邮件到 任何地址。
  • 另一个ASP.NET应用程序 相同的IIS运行在同一个IIS下 帐户(NETWORK SERVICE)可以发送 使用相同SMTP服务器的电子邮件 从任何地址到任何地址。
  • 未配置身份验证 在SMTP服务器上。
  • ASP.NET应用程序和 Windows窗体应用程序使用 System.Net.Mail.SmtpClient类 发送一个 System.Net.Mail.MailMessage。

发送电子邮件按摩的代码是:

private void button1_Click(object sender, EventArgs e)
        {
            MailMessage mesasge = new MailMessage(txtFrom.Text, txtTo.Text, "Test mail", txtBody.Text);
            SmtpClient client = new SmtpClient();
            if (!(string.IsNullOrEmpty(txtUserName.Text)))  //Is false since txtUserName.Text is empty
                client.Credentials = new System.Net.NetworkCredential(txtUserName.Text, txtPassword.Text);
            client.EnableSsl = false;
            client.Host = txtServer.Text;
            client.Port = 25;
            try
            {
                client.Send(mesasge);
            }
            catch (Exception ex)
            {
                txtResponse.Text = ex.Message;
            }
        }

据我所知,这应该是配置而不是编码问题。有谁知道问题可能是什么,也许这是如何解决的?感谢名单!

2 个答案:

答案 0 :(得分:1)

这绝对听起来像是身份验证问题,或者您无意中使用了2个不同的SMTP服务器。

我建议您在两个应用程序中启用日志记录,然后查看日志。当您查看日志时,您应该能够看到差异,并希望将其追溯到您的代码。

要在System.Net.Mail中登录,您需要在.config文件中添加一些条目。

<configuration>
  <system.diagnostics>
    <trace autoflush="true" />

    <sources>

      <source name="System.Net" >
        <listeners>
          <add name="MyTraceFile"/>
        </listeners>
      </source>

      <source name="System.Net.Sockets">
        <listeners>
          <add name="MyTraceFile"/>
        </listeners>
      </source>

    </sources>


    <sharedListeners>
      <add
        name="MyTraceFile"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="System.Net.trace.log"                />
    </sharedListeners>

    <switches>
      <add name="System.Net" value="Verbose" />
      <add name="System.Net.Sockets" value="Verbose" />
    </switches>
 </configuration>

这是一个包含更多信息的链接:

http://systemnetmail.com/faq/4.10.aspx

答案 1 :(得分:0)

你在web.config中有impersonate = true吗?

这样做:

new System.Net.NetworkCredential(txtUserName.Text, txtPassword.Text);

据我所知,要求将web.config设置为允许模拟。

尝试将此添加到web.config(如果你没有它)

    <system.web>
    <identity impersonate="true"  />