.NET Core中簡單的郵箱格式校驗方式

Intro

前段時間有一個驗證郵箱格式的小需求,然後突然發現瞭一種非常簡單的郵箱格式判斷方式

Implement

直接來看實現

public static bool IsEmailAddress(string email)
{
    if (string.IsNullOrWhiteSpace(email))
        return false;

    var symbolIndex = email.IndexOf('@');
    return symbolIndex > 0
        && symbolIndex < email.Length - 1
        && symbolIndex == email.LastIndexOf('@');
}

在之前的認知裡,一般判斷郵箱格式都是用一個正則表達式,有時候正則表達式還可能會特別復雜,在老的 .NET framework 中 EmailAddress 的判斷使用的是一個很復雜的一個正則表達式

const string pattern = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";

可以參考:https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/EmailAddressAttribute.cs,54

而在 .NET Core 中就比較簡單瞭,沒有用到正則,前面的實現也是來自於 .NET Core EmailAddressAttribute 的實現,實現如下:

public sealed class EmailAddressAttribute : DataTypeAttribute
{
    public EmailAddressAttribute()
        : base(DataType.EmailAddress)
        {
            // Set DefaultErrorMessage not ErrrorMessage, allowing user to set
            // ErrorMessageResourceType and ErrorMessageResourceName to use localized messages.
            DefaultErrorMessage = SR.EmailAddressAttribute_Invalid;
        }

    public override bool IsValid(object value)
    {
        if (value == null)
        {
            return true;
        }

        if (!(value is string valueAsString))
        {
            return false;
        }

        // only return true if there is only 1 '@' character
        // and it is neither the first nor the last character
        bool found = false;
        for (int i = 0; i < valueAsString.Length; i++)
        {
            if (valueAsString[i] == '@')
            {
                if (found || i == 0 || i == valueAsString.Length - 1)
                {
                    return false;
                }
                found = true;
            }
        }
        return found;
    }
}

通過這種方式,我們可以提高判斷郵箱格式的性能又不必維護正則表達式瞭。總結:有且僅有一個@並且前後都有字符

More

有一點需要註意,在上面的 EmailAddressAttribute 的實現中,如果值是 null 也會認為是“合法”的,這裡的“合法”並不是說郵箱格式合法而是說驗證可以通過,實際情況下一般我們是會認為這並不是一個合法的郵箱

References

  • https://github.com/dotnet/runtime/blob/main/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs

  • https://github.com/dotnet/runtime/blob/v5.0.0/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs

  • https://github.com/dotnet/corefx/blob/v3.0.0/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs

  • https://github.com/dotnet/corefx/blob/v2.2.0/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs

  • https://github.com/dotnet/corefx/blob/v2.0.0/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs

總結

到此這篇關於.NET Core中簡單的郵箱格式校驗方式的文章就介紹到這瞭,更多相關.NET Core郵箱格式校驗內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: