天天看點

郵件:事務失敗。 伺服器響應為:DT:SPM 163 smtp

幾年前我做的一個項目,日發郵件最高峰時幾十萬。自以為對郵件發送方面已經有了一定認識,是以近期機緣巧合之下,又有項目需要發送郵件,不禁自信滿滿,暗自慶幸能不手到擒來乎?

不想老革命遇到新問題。我原先的郵件發送機制,是生成eml檔案,然後扔到windows自帶的smtp伺服器的pickup目錄下,系統即自動發送(見拙作:​​郵件發送一點心得​​)。

但今時今日,這些好像都是老皇曆了。IIS7預設并沒有SMTP,如果作業系統是server,還可以通過添加功能加上去,但WIN7就不行了。偏偏,我們的系統就部署在WIN7下。

我第一個應對之道是看WIN7能不能裝那個自帶的SMTP,結果是不行,死活沒找到。

第二個辦法是裝個第三方的SMTP,找來找去,找到一個叫做什麼FREE SMTP的,裝上去以後,打開看,好像忒簡單了點。根本沒有啥PICK目錄的,應該是隻能通過代碼,搞什麼幾次握手之類的方法來進行調用。我很煩這個東西。

最後,決定還是直接使用smtp.163.com。網上例子比比皆是。

public interface IEmail
{
    bool Send(EmailParam param);
    string Mess { get; }
}
public class EmailParam
{
    public string From { get; set; }
    public string To { get; set; }//接收人;多個郵箱用分号隔開
    public string CC { get; set; }//抄送;多個郵箱用分号隔開
    public string Subject { get; set; }//标題
    public string Body { get; set; }//郵件正文
}

public class Sender : IEmail
{
    SmtpClient client;
    public Sender()
    {
        // <add key="eml_host" value="smtp.163.com"/>
        // <add key="eml_account" value="chendaqu"/>
        // <add key="eml_pwd" value="1234abcd"/>
        string host = ConfigurationManager.AppSettings["eml_host"];
        string account = ConfigurationManager.AppSettings["eml_account"];
        string pwd = ConfigurationManager.AppSettings["eml_pwd"];

        client = new SmtpClient();
        client.Host = host;
        client.UseDefaultCredentials = false;
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.Credentials = new System.Net.NetworkCredential(account,pwd);
        client.Port = 25;
    }
    public string Mess { get; set; }
    public bool Send(EmailParam param)
    {
        MailMessage mail = new MailMessage();

        mail.From = new MailAddress(param.From);
        getCollection(mail.To,param.To);
        getCollection(mail.CC, param.CC);
        mail.Subject = param.Subject;
        mail.Body = param.Body;
        mail.SubjectEncoding = Encoding.UTF8;
        mail.BodyEncoding = Encoding.UTF8;
        mail.Priority = MailPriority.Normal;
        mail.IsBodyHtml = true;
        mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;

        try
        {
            client.Send(mail);
        }
        catch(Exception ex)
        {
            Mess = ex.Message;
            return false;
        }

        return true;
    }
    MailAddressCollection getCollection(MailAddressCollection collection,string arstring)
    {
        if (!String.IsNullOrEmpty(arstring))
        {
            string[] ar = arstring.Split(';');
            foreach (string item in ar)
            {
                if (String.IsNullOrEmpty(item)) continue;
                collection.Add(item);
            }
        }
        return      

使用單元測試進行調用:

[TestMethod()]
public void SendTest()
{
    IEmail sender = new Sender();

    bool ok = sender.Send(new EmailParam()
    {
        Subject = "郵件測試7",
        Body = "Hello World!",
        From = "[email protected]",
        To = "[email protected];[email protected]",
    });

    Assert.AreEqual(true, ok);
}      

結果剛開始非常順利,都能收到郵件;但該單元測試運作了幾次以後,就發送失敗了。提示:

錯誤:郵件:事務失敗。 伺服器響應為:DT:SPM 163 smtp11,D8CowACXNqusR1pYQe3vGA--.16469S2 1482311598,please see http://mail.163.com/help/help_spam_16.htm?ip=219.136.75.223&hostid=smtp11&time=1482311598      

開始時以為是因為163郵箱的反垃圾郵件機制,猛查資料,結果一無所獲。焦慮攻心之下,我第二天居然感冒了。後來才知道是QQ郵箱的發垃圾郵件機制所緻。同一個發送請求中,有一個位址失敗,其他的都失敗了,是以稱為“事務”?

後來就是莫名其妙地好了,可能是郵件内容有所變化,QQ又認為它不是垃圾了。靠。

注:

我這個163郵箱,開啟了用戶端授權,未清楚對應對反垃圾機制是否有用,好像不開啟這個用戶端授權也能發送。開啟了這個用戶端授權後,代碼中的密碼要使用這個用戶端授權密碼,而不是登入郵箱的密碼。

繼續閱讀