使用 C# 发送电子邮件 - 不起作用,但没有抛出错误

发布于 2024-10-22 06:53:19 字数 4734 浏览 1 评论 0原文

正如主题标题所示,我正在尝试从我的 C# 应用程序发送电子邮件,但遇到了一些麻烦。

我编写了下面的函数,以便更轻松地从我的应用程序发送邮件,但我相信某个地方一定有问题,但我只是看不到它。也许这就是“只见树木,不见森林”的情况。

当我尝试通过 SMTP 发送电子邮件时出现问题。该页面似乎超时了,根本没有错误消息。LocalPickup 可以工作,指定取件目录也可以,但在本例中我需要使用 SMTP。

在本例中,我的网站位于我的家庭开发服务器(运行 Windows Server 2003)上,而我的 SMTP 服务器是一个运行 CentOS Linux 和 Qmail 的远程专用服务器。

我已经包含了我编写的函数,只是为了回答任何问题.. 是的,该服务器上的 SMTP 端口肯定是 26 ;)

    /// <summary>
    /// Sends an email
    /// </summary>
    /// <param name="To">Addresses to send the email to, comma seperated</param>
    /// <param name="subject">Subject of the email</param>
    /// <param name="emailBody">Content of the email</param>
    /// <param name="cc">CC addresses, comma seperated [Optional]</param>
    /// <param name="Bcc">BCC addresses, comma seperated [Optional]</param>
    /// <param name="client">How to send mail, choices: iis, network, directory. [Optional] Defaults to iis</param>
    /// <returns></returns>
    public bool sendMail(string To, string subject, string emailBody, string from, string cc = "", string Bcc = "", string client = "network", bool html = true)
    {

        // Create a mailMessage object
        MailMessage objEmail = new MailMessage();
        objEmail.From = new MailAddress(from);
        // Split email addresses by comma
        string[] emailTo = To.Split(',');
        foreach (string address in emailTo)
        {
            // Add these to the "To" address
            objEmail.To.Add(address);
        }

        // Check for CC addresses

        if (cc != "")
        {
            string[] emailCC = cc.Split(',');
            foreach (string addressCC in emailCC)
            {
                objEmail.CC.Add(addressCC);
            }
        }

        // Check for Bcc addresses

        if (Bcc != "")
        {
            string[] emailBCC = Bcc.Split(',');
            foreach (string addressBCC in emailBCC)
            {
                objEmail.Bcc.Add(addressBCC);
            }
        }

        // Set the subject.
        objEmail.Subject = subject;

        // Set the email body
        objEmail.Body = emailBody;

        // Set up the SMTP client

        SmtpClient server = new SmtpClient();


        switch (client)
        {
            case "iis":
                server.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
                break;
            case "network":
                server.DeliveryMethod = SmtpDeliveryMethod.Network;
                NetworkCredential credentials = new NetworkCredential("SmtpUserName", "SmtpPassword");
                server.Host = "SmtpHost";
                server.Port = 26;
                server.Credentials = credentials;
                break;
            case "directory":
                server.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
                server.PickupDirectoryLocation = "c:\\mailpickup";
                break;
            default:
                throw new Exception("Invalid delivery method specified, cannot continue!");

        }

        if (html)
        {
            // As the email is HTML, we need to strip out all tags for the plaintext version of the email.
            string s = emailBody;

            s = Regex.Replace(s, "<.*?>", string.Empty);
            s = Regex.Replace(s, "<script.*?</script>", "", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            AlternateView plainText = AlternateView.CreateAlternateViewFromString(s, null, MediaTypeNames.Text.Plain);
            objEmail.AlternateViews.Add(plainText);

            AlternateView rich = AlternateView.CreateAlternateViewFromString(emailBody, null, MediaTypeNames.Text.Html);
            objEmail.AlternateViews.Add(rich);
        }


        try
        {
            server.Send(objEmail);
            return true;
        }
        catch(Exception ex)
        {
            throw new Exception(ex.ToString());
        }

正如我所说,该页面在大约 60 秒后完全挂起,并且没有错误消息看到了。

提前致谢,

戴夫

添加: - 这就是我调用 sendMail() 的方式

webMail sendConfirmation = new webMail();

fileSystem fs = new fileSystem();
siteSettings setting = new siteSettings();
string mailBody = fs.file_get_contents("http://myurl.com/mymessage.html");

// Run any replaces.
mailBody = mailBody.Replace("{EMAIL_TITLE}", "Your account requires confirmation");
mailBody = mailBody.Replace("{U_FNAME}", u_forename);
mailBody = mailBody.Replace("{REG_URL_STRING}", setting.confirmUrl);


sendConfirmation.sendMail(u_emailAddress, "Your account requires confirmation", mailBody, setting.siteEmail);

as the topic title suggests, I am trying to send email from my C# application and i'm running into a little bit of trouble.

I wrote the function below in order to make it easier to send mail from my app, but i believe there must be a problem somewhere and I just can't see it. Perhaps it's the "Can't see the forest for the trees" scenario.

The problem occurs when I try to send email via SMTP. The page just seems to time out, with no error message, at all.. LocalPickup works, as does specifying a pickup directory, but in this instance I need to use SMTP.

In this case, my website is located on my home development server (running windows server 2003) and my SMTP server is a remote dedicated box running CentOS Linux with Qmail.

I've included the function I wrote, and just to answer any questions.. Yes, the SMTP port on this server is definately 26 ;)

    /// <summary>
    /// Sends an email
    /// </summary>
    /// <param name="To">Addresses to send the email to, comma seperated</param>
    /// <param name="subject">Subject of the email</param>
    /// <param name="emailBody">Content of the email</param>
    /// <param name="cc">CC addresses, comma seperated [Optional]</param>
    /// <param name="Bcc">BCC addresses, comma seperated [Optional]</param>
    /// <param name="client">How to send mail, choices: iis, network, directory. [Optional] Defaults to iis</param>
    /// <returns></returns>
    public bool sendMail(string To, string subject, string emailBody, string from, string cc = "", string Bcc = "", string client = "network", bool html = true)
    {

        // Create a mailMessage object
        MailMessage objEmail = new MailMessage();
        objEmail.From = new MailAddress(from);
        // Split email addresses by comma
        string[] emailTo = To.Split(',');
        foreach (string address in emailTo)
        {
            // Add these to the "To" address
            objEmail.To.Add(address);
        }

        // Check for CC addresses

        if (cc != "")
        {
            string[] emailCC = cc.Split(',');
            foreach (string addressCC in emailCC)
            {
                objEmail.CC.Add(addressCC);
            }
        }

        // Check for Bcc addresses

        if (Bcc != "")
        {
            string[] emailBCC = Bcc.Split(',');
            foreach (string addressBCC in emailBCC)
            {
                objEmail.Bcc.Add(addressBCC);
            }
        }

        // Set the subject.
        objEmail.Subject = subject;

        // Set the email body
        objEmail.Body = emailBody;

        // Set up the SMTP client

        SmtpClient server = new SmtpClient();


        switch (client)
        {
            case "iis":
                server.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
                break;
            case "network":
                server.DeliveryMethod = SmtpDeliveryMethod.Network;
                NetworkCredential credentials = new NetworkCredential("SmtpUserName", "SmtpPassword");
                server.Host = "SmtpHost";
                server.Port = 26;
                server.Credentials = credentials;
                break;
            case "directory":
                server.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
                server.PickupDirectoryLocation = "c:\\mailpickup";
                break;
            default:
                throw new Exception("Invalid delivery method specified, cannot continue!");

        }

        if (html)
        {
            // As the email is HTML, we need to strip out all tags for the plaintext version of the email.
            string s = emailBody;

            s = Regex.Replace(s, "<.*?>", string.Empty);
            s = Regex.Replace(s, "<script.*?</script>", "", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            AlternateView plainText = AlternateView.CreateAlternateViewFromString(s, null, MediaTypeNames.Text.Plain);
            objEmail.AlternateViews.Add(plainText);

            AlternateView rich = AlternateView.CreateAlternateViewFromString(emailBody, null, MediaTypeNames.Text.Html);
            objEmail.AlternateViews.Add(rich);
        }


        try
        {
            server.Send(objEmail);
            return true;
        }
        catch(Exception ex)
        {
            throw new Exception(ex.ToString());
        }

As I said, the page just hangs completely after about 60 seconds, with no error message to be seen.

Thanks in advance,

Dave

Addition: - This is how I am calling sendMail()

webMail sendConfirmation = new webMail();

fileSystem fs = new fileSystem();
siteSettings setting = new siteSettings();
string mailBody = fs.file_get_contents("http://myurl.com/mymessage.html");

// Run any replaces.
mailBody = mailBody.Replace("{EMAIL_TITLE}", "Your account requires confirmation");
mailBody = mailBody.Replace("{U_FNAME}", u_forename);
mailBody = mailBody.Replace("{REG_URL_STRING}", setting.confirmUrl);


sendConfirmation.sendMail(u_emailAddress, "Your account requires confirmation", mailBody, setting.siteEmail);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

转身以后 2024-10-29 06:53:19

您可以尝试检查是否有错误:

SmtpClient smtp = new SmtpClient();
            smtp.SendCompleted += new SendCompletedEventHandler(smtp_SendCompleted);
            smtp.Send(msgMail);

void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        if (e.Cancelled == true || e.Error != null)
        {
            throw new Exception(e.Cancelled ? "EMail sedning was canceled." : "Error: " + e.Error.ToString());
        }

you can try to check for error:

SmtpClient smtp = new SmtpClient();
            smtp.SendCompleted += new SendCompletedEventHandler(smtp_SendCompleted);
            smtp.Send(msgMail);

void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        if (e.Cancelled == true || e.Error != null)
        {
            throw new Exception(e.Cancelled ? "EMail sedning was canceled." : "Error: " + e.Error.ToString());
        }
勿忘初心 2024-10-29 06:53:19

找不到 rcpt 域的有效 MX 通常意味着无法找到有效的电子邮件地址或电子邮件域来将电子邮件转发至: 我会查看被拆分的“收件人”电子邮件地址数组,以确保每个地址都是有效的/来自有效域。可能会向每个“收件人”电子邮件地址发送一个测试,以便您可以验证这是否是 smtp 服务器问题。

另一种可能性是 localhost/iis 中继到另一个 smtp 服务器的权限“??”

我的单地址测试的测试代码:

public void Send(string from, string to,string smtpServer, int smtpPort,string username, string password)
        {
            try
            {
                using (MailMessage mm = new MailMessage())
                {
                    SmtpClient sc = new SmtpClient();
                    mm.From = new MailAddress(from, "Test");
                    mm.To.Add(new MailAddress(to));
                    mm.IsBodyHtml = true;
                    mm.Subject = "Test Message";
                    mm.Body = "This is a test email message from csharp";
                    mm.BodyEncoding = System.Text.Encoding.UTF8;
                    mm.SubjectEncoding = System.Text.Encoding.UTF8;
                    NetworkCredential su = new NetworkCredential(username, password);
                    sc.Host = smtpServer;
                    sc.Port = smtpPort;
                    sc.Credentials = su;
                    sc.Send(mm);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

can't find a valid MX for rcpt domain typically means a valid email address or email domain cannot be found to relay the email to: I would take a look at the array of "to" email addresses being split to ensure each one is valid/from a valid domain. Possibly send a single test to each "to" email address so you can verify if this is an smtp server issue.

Another possiblity is localhost/iis permissions for relaying to another smtp server "??"

My test code for single address tests:

public void Send(string from, string to,string smtpServer, int smtpPort,string username, string password)
        {
            try
            {
                using (MailMessage mm = new MailMessage())
                {
                    SmtpClient sc = new SmtpClient();
                    mm.From = new MailAddress(from, "Test");
                    mm.To.Add(new MailAddress(to));
                    mm.IsBodyHtml = true;
                    mm.Subject = "Test Message";
                    mm.Body = "This is a test email message from csharp";
                    mm.BodyEncoding = System.Text.Encoding.UTF8;
                    mm.SubjectEncoding = System.Text.Encoding.UTF8;
                    NetworkCredential su = new NetworkCredential(username, password);
                    sc.Host = smtpServer;
                    sc.Port = smtpPort;
                    sc.Credentials = su;
                    sc.Send(mm);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
客…行舟 2024-10-29 06:53:19

对于我的公司来说,出现此问题的原因是发送电子邮件的服务器或计算机未包含在电子邮件服务器的白名单中。一旦机器的 IP 地址被列入白名单,它就开始工作。出于同样的原因,您可能需要检查电子邮件服务器黑名单。

For my company, the reason we were having this issue was because the server or machine that was sending the emails was not included on the email server's white list. Once the machines ip address was white listed it started working. You might want to check the email servers black list for the same reason.

浮生面具三千个 2024-10-29 06:53:19

有时,以这种方式发送的邮件往往会成为垃圾邮件,特别是如果发件人地址是虚构的。正如 P.Brian.Macket 告诉你的那样,尝试使用 telnet 来使用原始 ftp 是个好主意。

Sometimes mails sent that way tends to finish into the spam, expecially if the from address is fantasious. Tryng the raw ftp with telnet as P.Brian.Macket tell you is a good idea.

多孤肩上扛 2024-10-29 06:53:19

您的默认客户端使用网络,但是当您定义网络客户端时,您正在使用一些默认代码(用户名、密码和主机)。

 case "network":
            server.DeliveryMethod = SmtpDeliveryMethod.Network;
            NetworkCredential credentials = new NetworkCredential("SmtpUserName", "SmtpPassword");
            server.Host = "SmtpHost";
            server.Port = 26;
            server.Credentials = credentials;
            break;

我真的认为正在使用示例代码而忘记指定您的自定义配置。

我为我的英语道歉。

your default client us network, but when you define the network client you are using some default code (username, password an host).

 case "network":
            server.DeliveryMethod = SmtpDeliveryMethod.Network;
            NetworkCredential credentials = new NetworkCredential("SmtpUserName", "SmtpPassword");
            server.Host = "SmtpHost";
            server.Port = 26;
            server.Credentials = credentials;
            break;

I really think that are using an example code and forget to specify your custom configuration.

I apologize for my english.

少钕鈤記 2024-10-29 06:53:19

“To”是 C# 中的保留字吗?尝试改变这个,看看你会得到什么。

Is "To" a reserved word in c#? Try changing this and see what you get then.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文