簡體   English   中英

為什么 MailAddress 認為“john@gmail”。 是一個有效的電子郵件地址嗎?

[英]Why does MailAddress think 'john@gmail.' is a valid email address?

像一個優秀的 C# 用戶一樣,我使用MailAddress對象來驗證電子郵件地址。

我的一個客戶輸入了john@gmail. 他的電子郵件,經過MailAddress驗證,破壞了我的軟件。 我希望下面的代碼拋出異常,但事實並非如此。

static void Main(string[] args)
{
    string addressmail = string.Empty;

    try
    {
        MailAddress mail = new MailAddress(@"john@gmail.");
        addressmail = mail.Address;
    }
    catch (FormatException)
    {
        // address is invalid
    }

    // address is valid
    Console.WriteLine(addressmail);
}

你知道如何捕捉這種虛假的郵件地址嗎?

我認為在這種情況下,MS 對有效電子郵件地址的實現是不正確的,至少根據RFC822 我還沒有真正嘗試過你的代碼,所以我假設它像你說的那樣。

還有其他方法可以驗證電子郵件地址,例如實際連接到 SMTP 服務器並要求它確認該地址是否有效(如此此處所述)。 不這樣做,你總是會遇到一些麻煩。 就我個人而言,我認為根據某些規范(除了我們可以使用的快速檢查;例如您的代碼)花費太多時間驗證電子郵件地址是不值得的 - 真正的測試是是否在該地址上收到電子郵件如果你發送它。 一個簡單的電子郵件驗證可以確認這一點,雖然我知道它可能並不適用於所有情況,但在那些情況下,你很不走運。

MailAddress 類型對驗證電子郵件地址的支持非常有限,並且從 .NET 4.0 開始,不支持大多數相關的 IETF 標准。 如果您需要驗證電子郵件地址的語法,可能不使用正則表達式,我建議您查看EmailVerify.NET ,這是一個支持有關該主題的所有當前標准的 .NET 組件(RFC 1123、RFC 2821 、RFC 2822、RFC 3696、RFC 4291、RFC 5321 和 RFC 5322)。 如果需要,該組件甚至允許對地址執行其他測試,包括 DNS、SMTP 和郵箱檢查。

免責聲明:我是該產品的首席開發人員。

MailboxValidator 有一個您可以使用的免費 API。 只需要在http://www.mailboxvalidator.com/plans#api上注冊免費的 API 計划,那么集成部分就很容易了,因為他們還有一個 C# 類http://www.mailboxvalidator.com/dotnet你來包裝 API 調用。

C# 類代碼位於https://github.com/MailboxValidator/mailboxvalidator-csharp

要通過 NuGet ( https://www.nuget.org/packages/MailboxValidator.SingleValidation/ ) 安裝 MailboxValidator SingleValidation 類, 在包管理器控制台中運行以下命令:

Install-Package MailboxValidator.SingleValidation

然后你可以像下面這樣使用這個類:

using System;
using System.Windows.Forms;
using MailboxValidator;

namespace TestMailboxValidatorCSharp
{
    public class TestMailboxValidatorCSharp
    {
        static void Main(string[] args)
        {
            var mbv = new SingleValidation("PASTE_YOUR_API_KEY_HERE");
            String results = "";
            try
            {
                MBVResult rec = mbv.ValidateEmail("example@example.com");

                if (rec.ErrorCode == "")
                {
                    results += "email_address: " + rec.EmailAddress + "\n";
                    results += "domain: " + rec.Domain + "\n";
                    results += "is_free: " + rec.IsFree + "\n";
                    results += "is_syntax: " + rec.IsSyntax + "\n";
                    results += "is_domain: " + rec.IsDomain + "\n";
                    results += "is_smtp: " + rec.IsSMTP + "\n";
                    results += "is_verified: " + rec.IsVerified + "\n";
                    results += "is_server_down: " + rec.IsServerDown + "\n";
                    results += "is_greylisted: " + rec.IsGreylisted + "\n";
                    results += "is_disposable: " + rec.IsDisposable + "\n";
                    results += "is_suppressed: " + rec.IsSuppressed + "\n";
                    results += "is_role: " + rec.IsRole + "\n";
                    results += "is_high_risk: " + rec.IsHighRisk + "\n";
                    results += "is_catchall: " + rec.IsCatchall + "\n";
                    results += "mailboxvalidator_score: " + rec.MailboxValidatorScore + "\n";
                    results += "time_taken: " + rec.TimeTaken + "\n";
                    results += "status: " + rec.Status + "\n";
                    results += "credits_available: " + rec.CreditsAvailable + "\n";
                }
                else
                {
                    results += "error_code: " + rec.ErrorCode + "\n";
                    results += "error_message: " + rec.ErrorMessage + "\n";
                }

                results += "version: " + rec.Version + "\n";
                MessageBox.Show(results);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
            }
        }
    }
}

以某種方式固定版本,混合 MailAddress 和一個簡單的 Regex 來驗證主機:

SLaks 建議的靜態正則表達式

private static readonly Regex hostReg = new Regex(@"(\w+)\.(\w+)");

public bool IsMailAddress(string addParam)
        {
            try
            {
                MailAddress mail = new MailAddress(addParam);
                string address = mail.Address;

                //not handled by MailAdress, which is a shame
                return hostReg.IsMatch(mail.Host);
            }
            catch (FormatException)
            {
                //address is invalid
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }

MailAddress 嘗試與廢棄 RFC822 的 RFC2822 兼容。 當您閱讀 MailAddress 的源代碼時,您會看到接受它的結尾點只是為了與某些電子郵件客戶端兼容。 使用正則表達式驗證電子郵件地址不是正確的做法(參見 RFC2822),最好的方法是實現解析器,MailAddress 所做的。

請參閱 MailAddressParser 使用的 DotAtomReader

不是免費的解決方案,但Cobisi 的電子郵件驗證庫可以在不同的准確度(語法、IspSpecificSyntax、DeaDomain、Dns、DeaMailExchanger、Smtp、Mailbox、CatchAll)內判斷電子郵件是否有效

var engine = new VerificationEngine();
var result = engine.Run("john@example.com",
                        VerificationLevel.Mailbox).Result;

if (result.LastStatus == VerificationStatus.Success)
{
    // TODO: Show a message box with the great news
}

免責聲明:我與公司或項目無關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM