.NET Core中简单的邮箱格式校验方式

2022-04-17 09:47:12
目录
IntroImplementMoreReferences总结

Intro

前段时间有一个验证邮箱格式的小需求,然后突然发现了一种非常简单的邮箱格式判断方式

Implement

直接来看实现

publicstaticboolIsEmailAddress(stringemail){if(string.IsNullOrWhiteSpace(email))returnfalse;varsymbolIndex=email.IndexOf('@');returnsymbolIndex>0&&symbolIndex<email.Length-1&&symbolIndex==email.LastIndexOf('@');}

在之前的认知里,一般判断邮箱格式都是用一个正则表达式,有时候正则表达式还可能会特别复杂,在老的 .NET framework 中 EmailAddress 的判断使用的是一个很复杂的一个正则表达式

conststringpattern=@"^((([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+(.([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+)*)|((x22)((((x20|x09)*(x0dx0a))?(x20|x09)+)?(([x01-x08x0bx0cx0e-x1fx7f]|x21|[x23-x5b]|[x5d-x7e]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(\([x01-x09x0bx0cx0d-x7f]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))))*(((x20|x09)*(x0dx0a))?(x20|x09)+)?(x22)))@((([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))).)+(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|[u00A0-uD7F易采站长站FuF900-uFDCFuFDF0-uFFEF]))).?$";

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

而在 .NET Core 中就比较简单了,没有用到正则,前面的实现也是来自于 .NET Core EmailAddressAttribute 的实现,实现如下:

publicsealedclassEmailAddressAttribute:DataTypeAttribute{publicEmailAddressAttribute():base(DataType.EmailAddress){//SetDefaultErrorMessagenotErrrorMessage,allowingusertoset//ErrorMessageResourceTypeandErrorMessageResourceNametouselocalizedmessages.DefaultErrorMessage=SR.EmailAddressAttribute_Invalid;}publicoverrideboolIsValid(objectvalue){if(value==null){returntrue;}if(!(valueisstringvalueAsString)){returnfalse;}//onlyreturntrueifthereisonly1'@'character//anditisneitherthefirstnorthelastcharacterboolfound=false;for(inti=0;i<valueAsString.Length;i++){if(valueAsString[i]=='@'){if(found||i==0||i==valueAsString.Length-1){returnfalse;}found=true;}}returnfound;}}

通过这种方式,我们可以提高判断邮箱格式的性能又不必维护正则表达式了。总结:有且仅有一个@并且前后都有字符

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

总结