目录

介绍

电邮地址格式

1. Address

2. addr-spec

有效的电子邮件地址

显示名称

注释

引号

一些看起来很奇怪的有效地址

Domain-Part要求

不使用ASCII字符(UTF8)

长度限制

非法的电子邮件地址

推荐建议

使用代码

配置EmailTextBox

实例属性

静态特性

获取代码


验证电子邮件地址很困难,因为构成有效电子邮件地址的规范允许使用大量电子邮件。试图将这些规范转换为适当的Regex会导致庞大而复杂的表达式,但仍可能无法涵盖所有​​情况。本文介绍如何合理地完成电子邮件地址验证,并提供生产质量代码WPF文本框,包括让用户仅输入有效的击键(keystrokes),控制是否必须输入电子邮件地址(必填字段),,以及在用户试图关闭窗口而不保存所做的更改时发出警报。

介绍

编写用于验证电子邮件地址的WPF控件是一个挑战,因为几乎允许所有Unicode字符和许多格式。规范允许使用多种格式,但实际上只使用了很少的格式,因为异国情调的格式可能会被某些电子邮件软件(Outlook等客户端,Exchange等服务器)拒绝。控件必须足够灵活才能满足您的要求,即,如果您需要使用精确格式的严格控件,或者只想在用户键入奇怪的电子邮件地址时提醒用户。当然,最好的办法是防止用户进行无效的输入并控制用户可以进行的击键(keystrokes)。由于此控件是WpfWindowLib的一部分,因此如果需要或缺少电子邮件地址,它不允许用户保存数据。它还会通知用户是否试图关闭窗口而不保存数据。

电邮地址格式

相关规范可以在RFC 5322:Internet消息格式:地址规范中找到。

它通过两个步骤定义了一个有效的电子邮件地址:

1. Address

这个更高的级别指定了一个Address 可以包含一个display-name和一个Addr-Spec,这是我们在谈论电子邮件地址时通常指的部分。Address 看起来是这样的:

John Doe<John.Doe@example.com>

  • 显示名称为“John Doe”。它不用于电子邮件的路由,但允许以更加用户友好的形式显示电子邮件地址。
  • “<John.Doe@example.com>”:在规范angle-addr中被调用,并在尖括号中包含addr-spec(用于路由电子邮件的电子邮件地址)。

显示名称是可选的。如果没有显示名称,则不需要尖括号。

2. addr-spec

这部分描述通常称为电子邮件地址的内容:

John.Doe@example.com

基本上,地址分为两部分:

local-part @ domain-part

domain-part是电子邮件服务器的互联网DNS地址,同时local-part是该电子邮件服务器中的“信箱”的名称。domain-part的定义非常明确,每个人都需要了解电子邮件地址的路由,而本地部分的确切含义是由接收电子邮件服务器软件定义的,发件人不一定需要了解本地部分结构。该规范希望给电子邮件服务器尽可能的自由,这使得很难验证电子邮件地址是否正确。

有效电子邮件地址的唯一公认的要求是:

必须有两个部分,正好用'@'分隔。

但是,即使这个简单的规范也不总是正确的,因为以下也是有效的电子邮件地址:

"John@Doe"@example.com

第一个'@'在带引号的字符串中。所有可见的ASCII字符(即,从0x21到0x7E)被允许在local-part中使用,当它们被引用时。它们可以在两个引号'“'之间,也可以在单个特殊字符后加反斜杠'\':

John\@Doe@example.com (这是与上面带有引号的字符串相同的地址)。

有效的电子邮件地址

(灵感来自https://en.wikipedia.org/wiki/Email_address#Examples和RFC 3696名称检查和转换的应用技术:电子邮件地址的限制)

simple@example.com

域(Domain)应该包含“.”,因为根域不能是电子邮件服务器的地址。当然,对于大多数规则,也有一个例外:example@localhost。该域地址不是用于Internet,而是用于公司的内部网络。

x@example.com
一个字母的local-part是可以的。

John.Doe@example.com
句点“.”字符遵循一些特殊的规则:它不能是local-part或domain-part的第一或的最后一个字母并不能有连续的2个点像“..”。

Gmail将“John.Doe”和“JohnDoe”视为相同的地址。如上所述,由接收电子邮件服务器决定如何解释其邮箱地址。但是,当使用电子邮件地址来标识个人(例如登录页面)时,就会出现问题。是否会假设John.Doe@ example.com和JohnDoe@ example.com是2个不同的人?

-minus-sign-@example.com
_under_score_@example.com
连字符'-'和下划线'_'任何地方都可以接受

John.Doe+Filter@example.com

可能合法,但是所有电子邮件软件都可以理解吗?某些电子邮件服务器将使用“John.Doe”作为实际邮箱名称,并忽略“+”及其后的所有内容,直到“@”为止。

实际上,所有这些字符在local-part!#$%&'* +-/ =?^ _` . {| }〜中都是合法的。但并非所有电子邮件软件都可以接受它们。O'Leary@example.com较差,一些电子邮件客户端只是将其发送到OLeary@example.com。

显示名称

“<”和“>”字符不在上面的列表中,因为它们具有特殊含义,它们将“显示名称”与实际的“电子邮件地址”分开:
My Name <MyName@Example.com>
显示名称只能在尖括号中的电子邮件地址之前。它可以包含相同的字符,例如电子邮件地址和空格。

注释

在上面的列表中括号'('还缺少')'。它们包含注释:
Name(Comment1)<(Comment2)Name(Comment3)@(Comment4)Example.com(Comment5>(Comment2)
注释放在圆括号中。注释可以包含任何可打印的ASCII字符,但'(',')'和'\'除外。这严格按照RFC5322进行,但是我想很多电子邮件软件都无法正确解释它。如上所述,有些人甚至将其用作显示名称,这是错误的。如果可能的话,请勿使用注释。

引号

" "@example.org
引号之间的空格是邮箱的名称。在2个双引号之间,几乎没有任何变化。这使验证变得困难。

"john..doe"@example.org
带双引号的引号,不允许带引号

Some\@saple@example.com
第一个@应被视为一个简单的文字,而不是作为控制字符从domain-part分隔local-part。

John\ Doe@example.com
空格只允许被引用(在RFC的说法中,引用也意味着一个前导反斜杠'\'。

John.\\Doe@example.com
第一个反斜杠“\”使第二个反斜杠“\”成为普通字符。

一些看起来很奇怪的有效地址

"very.(),:;<>[]\".VERY.\"very@\ \"very\".unusual"@strange.example.com

mailhost!username@example.org
用于uucp邮件的分类主机路由

user%example.com@example.org
%通过example.org路由到了user@example.com

Domain-Part要求

domain-part是一个DNS主机名,由字母、数字、连字符和点组成。在极少数情况下,可以改用IP地址,并用方括号括起来:
John.Doe@[192.168.0.0]
user@[IPv6:2001:db8::1]

不使用ASCII字符(UTF8)

rfc6530,rfc6531,rfc6532指定在电子邮件软件支持的情况下如何将任何UTF字符用于电子邮件地址。由于电子邮件通常是从服务器转发到另一台服务器...,这很可能是这些服务器之一不支持UTF8,并且向发件人返回了一条错误消息,提示无法发送电子邮件。出于这个原因,尽管以下示例实际上是有效的地址,但是不要对电子邮件地址使用UTF8是更安全的:

Pelé@example.com
δοκιμή@παράδειγμα.δοκιμή
我買@屋企.香港
संपर्क@डाटामेल.भारतारत

尤其麻烦的是domain-part,因为必须从可能不支持UTF8的DNS服务器中查找实际IP地址。因此,发明了PunyCode,它以纯ASCII编码UTF8,然后也可以由无UTF8域服务器处理。但是您的电子邮件软件是否支持Punycode?

如前所述,目标是使用不会引起麻烦的电子邮件地址。使用基于UTF8的地址会带来麻烦。如果必须的话,请接受UTF8,但是如果不这样做,您的生活会轻松得多。

长度限制

除了语法限制外,电子邮件地址还有长度限制。该限制最大为64个字符(UTF8字节),local-part最大为255个字符(UTF8字节),domain-part总长度为320个字符。

非法的电子邮件地址

如上所述,电子邮件地址有许多有效的结构。但是也有非法的:

Abc.example.com
没有@字符

A@b@c@example.com
用引号引起来的字符串之外只能有一个@,除非用引号引起来

john..doe@example..com

任何地方都不允许双点'..'

a"b(c)d,e:f;g<h>i[j\k]l@example.com
此local-part中的特殊字符均不能使用引号引起来

just"not"right@example.com
用引号引起来的字符串必须用点分隔,或组成local-part的唯一元素

1234567890123456789012345678901234567890123456789012345678901234+x@example.com
local-part超过64个字符

推荐建议

  • 如果用户输入的电子邮件地址看起来很奇怪,则向用户发出警告。很可能是拼写错误,但也可能只是一个看起来很奇怪但有效的电子邮件地址。由用户决定。
  • 通过减少可输入的字符集来帮助用户限制可能犯的错误数量。如果可能,请避免使用UTF8。

编写电子邮件验证以正确识别所有合法和非法电子邮件地址非常困难,有人说几乎是不可能的。即使有可能,也并不意味着该电子邮件地址确实有效。验证的唯一方法是发送电子邮件并等待回复。因此,最好是使用一个相对简单的验证来警告用户,如果某些东西看起来很奇怪,从而发现错别字,但将最终决定权留给用户。

使用代码

<wwl:CheckedWindow x:Class="Samples.SampleWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:wwl="clr-namespace:WpfWindowsLib;assembly=WpfWindowsLib"SizeToContent="WidthAndHeight"><StackPanel><Label Content="Name (required)"/><wwl:CheckedTextBox x:Name="NameTextBox" MinWidth="100" IsRequired="True"/><Label Content="Email (not required)"/><wwl:EmailTextBox x:Name="EmailTextBox" MinWidth="100"/><Button x:Name="SaveButton" Content="_Save"/></StackPanel>
</wwl:CheckedWindow>

显示的上部窗口是带有名称TextBox的数据输入窗口,用户在保存之前必须在其中输入一些数据,以及EmailTextBox。TextBox需要一个名字,但用户没有输入任何数据,这就是为什么背景是卡其色。这也是禁用“保存按钮的原因。用户已输入电子邮件地址。然后,用户尝试关闭窗口而不保存数据。打开第二个警告窗口,“电子邮件TextBox”的背景变为浅绿色,以向用户显示哪些数据已更改。有关如何工作的详细说明,请参阅我的文章“用于数据输入的基本WPF窗口功能”。

在此屏幕快照中,用户输入了名称。因此保存按钮被激活。用户单击“保存按钮,但收到警告,因为该电子邮件地址看起来很奇怪(不是在domain-part中的“.”),然后可以决定是否应保存该电子邮件地址或是否需要进一步编辑。

配置EmailTextBox

在许多情况下,您无需进行任何配置。您可能要在XAML中进行设置IsRequired,或者,如果用户要编辑一些现有数据,则调用Initialise()传递现有电子邮件地址并将其isRequired作为后面代码中的参数的电话。

实例属性

可以为每个PhoneTextBox属性分别设置一些属性:

  • IsRequired(DependencyProperty):是否需要用户为该控件提供值?
  • MaxLength (DependencyProperty):可以在文本框中手动输入的最大字符数。

静态特性

一些属性适用于每个PhoneTextBox属性,因此声明为static:

  • AsciiSpecialChars (string):电子邮件地址local-part中字母和数字之外的其他字符。默认值:“.@-_+”。要允许更多字符,请分配您自己的字符串或调用EmailTextBox.SetExtendedAsciiSpecialChars()或EmailTextBox.SetExtendedQuotedAsciiSpecialChars()。
  • IsBlankAllowed:设置为true用户是否应该能够键入空白。
  • IsInternationalCharSetAllowed:设置为true用户是否应该能够使用大于0x7F的Unicode字符。
  • IsValidEmailChar(Func<char, bool>):被调用以验证电子邮件地址local-part中是否允许用户刚刚输入的字符。如果要使用其他验证,请分配自己的函数。
  • IsValidDnsChar(Func<char, bool>):被调用以验证电子邮件地址domain-part中是否允许用户刚刚输入的字符。如果要使用其他验证,请分配自己的函数。
  • IsValidEmail(Func<string, bool>):一旦键盘焦点离开EmailTextBox,就会被调用以验证完整的电子邮件地址。如果要使用其他验证,请分配自己的函数。
  • ShowLooksStrangeWarning(Func<EmailTextBox, bool>):IsValidEmail 检测到问题时被调用。如果您想以不同的方式显示问题,请分配自己的函数。

获取代码

可从Github获得最新版本:https://github.com/PeterHuberSg/WpfWindowsLib。

将所有内容下载或克隆到您的PC,这为您提供了以下项目的解决方案WpfWindowsLib:

  • WpfWindowsLib:(Dll)要从您的其他解决方案中引用,包含EmailTextBox
  • SamplesWPF Core应用程序显示所有WpfWindowsLib 控件
  • WpfWindowsLibTest:几乎没有WpfWindowsLib单元测试

电子邮件地址验证:详细解释,生产质量WPF文本框代码相关推荐

  1. c语言检测邮箱地址,C语言实现电子邮件地址验证程序

    我们最经常遇到的验证,就是电子邮件地址验证.网站上常见.各种网页脚本也都常用"正则表达式"(regular expression)对我们输入的电子邮件地址进行验证,判断是否合法.有 ...

  2. 【机器学习】交叉验证详细解释+10种常见的验证方法具体代码实现+可视化图

    [机器学习]交叉验证详细解释+10种常见的验证方法具体代码实现+可视化图 一.使用背景 由于在训练集上,通过调整参数设置使估计器的性能达到了最佳状态:但在测试集上可能会出现过拟合的情况. 此时,测试集 ...

  3. php邮件代码c语言,C++_C语言实现电子邮件地址验证程序,我们最经常遇到的验证,就是 - phpStudy...

    C语言实现电子邮件地址验证程序 我们最经常遇到的验证,就是电子邮件地址验证.网站上常见.各种网页脚本也都常用"正则表达式"(regular expression)对我们输入的电子邮 ...

  4. Wpf 文本框模糊匹配

    Wpf 文本框模糊匹配 源码下载地址 实现效果如图 整体实现不怎么难就不一一介绍了,主要是用了Popup 以及keyup 事件 这里有一个问题是style 中绑定属性不能直接用(这个地方我准备有时间了 ...

  5. WPF 文本框添加水印效果

    有的时候我们需要为我们的WPF文本框TextBox控件添加一个显示水印的效果来增强用户体验,比如登陆的时候提示输入用户名,输入密码等情形.如下图所示: 这个时候我们除了可以修改TextBox控件的控件 ...

  6. wpf文本框限制输入长度_Excel办公实操,限制输入日期,手机号码,不重复数据的使用...

    限制只能输入当前日期之前的日期 图是某企业的入库登记表,用来登记不同日期各品名和型号的入库信息.其中A列是产品入库的日期,要求必须为当前日期之前的日期,为了防止工作人员将入库日期输入为当天以后的日期, ...

  7. 如何在与 WPF 文本框的触摸交互中显示触摸键盘

    Windows Presentation Foundation (WPF) 应用程序在支持触控的世界中会遇到一些困难.在 WinRT 应用程序中,当文本字段获得焦点时,触摸键盘会自动显示,这样用户就可 ...

  8. android edittext email,Android上EditText上的电子邮件地址验证

    慕姐8265434 要执行电子邮件验证,我们有很多方法,但是最简单,最简单的方法是两种方法.1-使用EditText(....).addTextChangedListener它持续在EditText ...

  9. java程序中,数据验证,如何判断输入的文本框中的值是不是int型?

    String str1=jTextField1.getText(); str1=str1.replaceAll("[0-9]","");//将所有的数字型字符替 ...

最新文章

  1. redis stream java消息队列_Redis-消息队列的两种实现方式
  2. python ipaddr库_用Python脚本查询纯真IP库QQWry.dat(Demon修改版)
  3. 服务计算与服务生态系统 第一章测验题答案
  4. JavaScript 简介第一课
  5. python学习笔记——捌 ScoketServer
  6. WPS vba宏插件安装包
  7. 模拟电路,包括低频(模拟电子技术基础)和高频(高频电子线路)
  8. SSh三大框架工作原理介绍
  9. LORD MicroStrain 惯性传感系统
  10. 书单丨压箱底儿的10本传世计算机经典著作
  11. 一款逼疯妹子的撩妹神器
  12. 新时代动画电影的互联网宣传
  13. [无线运营] 841N做覆盖已运行两年,现改用941N刷UBNT做覆盖!多图更新
  14. 什么是bypass?什么是旁路交换机?为什么需要旁路交换机?
  15. 【数学之美】第三版推荐序二 摘录
  16. idea:使用easyYapi插件导出yapi接口
  17. 基于RV1126 Video分析-----sensor模块所代表的subdev子设备注册
  18. matlab求圆台模型,使用Matlab画出圆台圆锥圆柱
  19. 强制双休!传腾讯调整加班机制,21 点前必须离开工位!
  20. Mybatis入门很难吗?

热门文章

  1. api laravel 统一返回方法_Laravel-自定义API返回的JSON格式
  2. rpm打包的流程包括以下哪些_品牌策划的流程包括哪些?
  3. python标志变量_Python 中的 global 标识对变量作用域的影响
  4. 正能量励志文字手机壁纸
  5. 你在为疯狂圣诞节海报做准备了么?
  6. 创意促销海报设计思路,年底忙的设计师来看!
  7. 保姆级My SQL-5.7.19安装教程
  8. C++ Socket通信类的封装(还有点小bug)
  9. C++ new和malloc区别
  10. C语言为四维数组申请动态内存空间的方法(二)