【问题标题】:Users receive cdo messages as plain text用户以纯文本形式接收 cdo 消息
【发布时间】:2013-12-14 08:12:32
【问题描述】:

我有一个需要发送电子邮件的 ASP.NET 应用程序。起初我使用 System.Net.Mail,一切都很好。我的应用程序可以发送 html 消息,人们收到它们就好了。

但后来我们添加了一个新的 Web 服务器,该 Web 服务器需要 SSL 才能使用不同的 smtp 服务器发送电子邮件。所以我不得不使用 cdo 消息而不是 System.Net.Mail。 见How can I send emails through SSL SMTP with the .NET Framework?

现在发生了一件非常奇怪的事情。原始服务器以纯文本格式发送电子邮件,而第二个服务器以 html 格式发送电子邮件。两台服务器都使用完全相同的代码(在本文末尾)。唯一的区别是原始服务器不需要用户名和密码,而第二个服务器则需要。

另一个区别是第一台服务器运行的是 Windows Server 2008 R2,而第二台服务器运行的是 Windows Server 2012。但我认为这两个版本之间的 cdo 没有变化,对吧?

我不知道如何解决这个问题。问题不在代码中,因为第二台服务器工作正常,也不在第一台服务器正在使用的 smtp 服务器中,因为它与 System.Net.Mail 一起工作正常。有什么想法吗??

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Net.Configuration;
using System.Net.Mail;
using System.Runtime.InteropServices;

namespace Kernel
{
    public class cdoMessage
    {
        public String Host;
        public String Username;
        public String Password;
        public Int32 Port;
        public Boolean EnableSsl;
        public String From;
        public MailAddressCollection To;
        public Boolean IsBodyHtml;
        public String Subject;
        public String Body;
        public MailAddressCollection Bcc;

        public cdoMessage()
        {
            SmtpSection settings = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");

            Host = settings.Network.Host;

            Username = settings.Network.UserName;

            Password = settings.Network.Password;

            Port = settings.Network.Port;

            EnableSsl = settings.Network.EnableSsl;

            From = settings.From;

            To = new MailAddressCollection();            

            IsBodyHtml = false;

            Bcc = new MailAddressCollection();
        }

        String s(String e)
        {
            return "http://schemas.microsoft.com/cdo/configuration/" + e;
        }

        public void Send()
        {

            CDO.Message message = new CDO.Message();

            try
            {
                message.Configuration.Fields[s("smtpserver")].Value = Host;

                message.Configuration.Fields[s("smtpserverport")].Value = Port;

                message.Configuration.Fields[s("sendusing")].Value = CDO.CdoSendUsing.cdoSendUsingPort;

                if (Username == null && Password == null)
                {
                    message.Configuration.Fields[s("smtpauthenticate")].Value = CDO.CdoProtocolsAuthentication.cdoAnonymous;
                }
                else
                {
                    message.Configuration.Fields[s("smtpauthenticate")].Value = CDO.CdoProtocolsAuthentication.cdoBasic;

                    message.Configuration.Fields[s("sendusername")].Value = Username;

                    message.Configuration.Fields[s("sendpassword")].Value = Password;
                }

                if (EnableSsl)
                {
                    message.Configuration.Fields[s("smtpusessl")].Value = "true";
                }

                message.Configuration.Fields.Update();

                message.From = From;

                // ToString works just fine.
                message.To = To.ToString();

                message.BCC = Bcc.ToString();

                message.Subject = Subject;

                if (IsBodyHtml)
                {
                    message.HTMLBody = Body;
                }
                else
                {
                    message.TextBody = Body;
                }

                message.Send();
            }
            finally
            {
                Marshal.ReleaseComObject(message);
            }
        }
    }
}

【问题讨论】:

  • 我看到了IsBodyHtml = false;,所以除非你明确地将IsBodyHtml 属性设置为true,否则正文会被写入TextBody。你能添加使用这个类 cdoMessage 的代码吗?两台机器上也是一样的吗?
  • 感谢您的回复!我放弃了这个。 IsBodyHtml 在调用 Send 之前设置为 true,两台机器的代码完全相同。一个有效,另一个无效。我有一个疯狂的想法,用 2012 年的那个替换 2008 年服务器中的 dll,看看会发生什么。我会及时通知你。
  • 我们可以责怪新的 smtp 服务器吗?它可能会将您的消息转换回纯文本吗?您是否尝试过使用普通客户端通过服务器发送 HTML 电子邮件?
  • 在服务器 A 中,使用 System.Net.Mail 时,电子邮件是 HTML 格式,但使用 cdo 时,它们是纯文本格式。
  • 为什么不在端口 587 而不是 465 上使用显式 SSL?这由 System.Net.SmtpClient 支持,实际上是标准中实际定义的唯一方法

标签: c# asp.net email ssl


【解决方案1】:

这是一个免费的库,它在 explicitimplicit 模式下对 POP3、SMTP、IMAP 提供 SSL\TLS 支持。显然我没有使用过它,但它的功能看起来相当复杂。这个价格绝对值得一试。

http://visualstudiogallery.msdn.microsoft.com/28b96cd4-b755-48a0-b686-9abb7d5607a8

【讨论】:

    【解决方案2】:

    我记得这件事发生的原因很奇怪:

    如果正文中的行太长,即使我们以 HTML 格式发送邮件,SMTP 服务也会以纯文本形式发送邮件。尝试通过插入 \n 换行符将邮件正文分成较短的行。虽然我不能说这些行可能有多长。

    【讨论】:

    • 谢谢!这可能是问题所在。我会测试看看。
    • 这不起作用。我尝试使用

      A

      发送电子邮件,但它仍然显示为纯文本。
    【解决方案3】:

    尝试将.HTMLBody.TextBody 都设置为您想要的值。理想情况下,纯文本和 html 的不同版本。通常,如果没有,则为 html。 Html 在大多数读者中被认为是“替代”显示文本,至少在当时是这样。也许不同的 SMTP 服务器处理丢失的电子邮件字段的方式不同。

    如果这不能解决问题,请在两个字段中发送纯文本,然后查看两个服务器是否相同。

    如果这不起作用,请通过服务器 A 转发来自服务器 B 的电子邮件,反之亦然,看看会发生什么。即使您只是从电子邮件阅读器手动执行此操作。这很可能是第二个 SMTP 服务器上的一个设置,默认情况下以纯文本形式发送。

    查看从两个服务器接收到的消息中的 MIME 标头。寻找不同之处,以便您了解实际不同之处。

    您最终应该能够确定发生了什么以及发生在哪里。

    更新

    输入您的凭据并尝试一下。它通过 SSL 将邮件发送到我的 gmail 地址。尝试发送到您的旧服务器。

        public bool SendMail() {
            var client = new SmtpClient("smtp.gmail.com", 587) {
                Credentials = new NetworkCredential("your email", "password"),
                EnableSsl = true
            };
    
            MailMessage message = new MailMessage(
                new MailAddress("from email address"),
                new MailAddress("to email address")) {
                    Body = "This is a test e-mail message sent using SSL ",
                    Subject = "Test email with SSL and Credentials"
                };
    
            try {
                client.Send(message);
            } catch (Exception ex) {
                Console.WriteLine("Exception is:" + ex.ToString());
            }
    
            return false;
        }
    

    【讨论】:

    • 谢谢!我会尝试你的建议并看看。在发布问题之前,我确实查看了好服务器和坏服务器的标题。坏服务器正在剥离 html 标签并以纯文本形式发送消息: Content-Type: text/plain; charset="iso-8859-1" X-MimeOLE: 微软出品 MimeOLE V6.1.7601.17609 纯文本 虽然好服务器: Content-Type: multipart/alternative; boundary="----=_NextPart_000_0000_01CEF687.3EEA8DA0" X-MimeOLE:由 Microsoft MimeOLE V6.3.9600.16384 生成纯文本 ------=_NextPart_000_0000_01CEF687.3EEA8DA0 内容类型:文本/html 格式化文本
    • 所以我将 .TextBody 设置为

      A

      ,然后将其设置为 .HTMLBody ,我将电子邮件中的 html 标签视为字符,而不是呈现。不幸的是,服务器在防火墙后面,所以我无法交叉测试
    • 在 MIME 内容中是否包含 html 版本?换句话说,文本和 html 版本是否都通过了,而读者显示的是错误的版本?如果是这样,您是否使用相同的电子邮件阅读器来查看来自两台服务器的电子邮件?如果这不是问题,您是托管自己的电子邮件服务器还是由供应商维护?如果是供应商,请联系他们并解释问题,如果不是,您将需要系统管理员的帮助。如果 MIME 内容相同,那就是你的阅读器。如果它们不同,则为邮件服务器。
    • 谢谢。 html部分消失了,只剩下带有标签的纯文本。
    • 您尝试过 Panagiotis Kanavos 的解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    相关资源
    最近更新 更多