我可以在System.Net.Mail中关闭电子邮件地址validation吗?

我正在尝试使用电子邮件与传真服务器软件交谈。 传真服务器将接受格式化的SMTP邮件并将其转换为传真,并将它们发送到地址中定义的传真号码。 这是通过从同一服务器从Outlook发送电子邮件手动测试的。

这是我的问题 – System.Net.Mail抛出一个System.FormatException: The specified string is not in the form required for an e-mail address. 由于我尝试发送到的电子邮件地址的格式而导致的exception

有什么方法可以关闭/更改此validation,因为电子邮件地址可能不符合RFC,但如果电子邮件被发送,它将起作用

即我想发送到[RFax:User @ / FN = 0123456789],包括方括号

您可以在Outlook中将其作为电子邮件地址发送

干杯克里斯

编辑

这是我用来绕过validation的类的简化版本。 有两种方法 – 一种是通过覆盖构造函数并直接设置内部属性,另一种是使用内部构造函数。 如果电子邮件地址中有空格,它们的效果会略有不同

 using System; using System.Reflection; namespace Mail { public class UnverifiedEmailAddress : System.Net.Mail.MailAddress { ///  /// Constructor to bypass the validation of MailAddress ///  /// Email address to create public UnverifiedEmailAddress(string address) : base("a@a") { FieldInfo field = typeof(System.Net.Mail.MailAddress).GetField("address", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(this, address); } ///  /// Static method to create an unverifed email address bypassing the address validation ///  /// Email address to create /// Display name for email address ///  private static System.Net.Mail.MailAddress GetUnverifiedEmailAddress(string address, string displayName) { ConstructorInfo cons = typeof(System.Net.Mail.MailAddress).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(string), typeof(string), typeof(UInt32) }, null); object obj = cons.Invoke(new object[] { address, displayName, UInt32.MinValue }); System.Net.Mail.MailAddress toAddressObj = (System.Net.Mail.MailAddress)obj; return toAddressObj; } } } 

不,你不能关闭那个validation。

编辑:

看了一下之后,似乎以下代码片段是一个可行的解决方法:

 ConstructorInfo ctor = typeof(MailAddress).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string), typeof(string) }, null); MailMessage msg = new MailMessage { To = { (MailAddress)ctor.Invoke(new object[] { null, "[RFax:User", "/FN=0123456789]" }) } }; 

这里有两个技巧。 第一个是使用不解析/validation提供的地址的内部MailAddress构造函数。

第二个技巧是在@ -sign上拆分“传真地址”并将其作为两部分( 用户 )传递。 这是必需的,因为稍后使用MailAddress.Address属性由框架编写SMTP To-header,并且该属性返回user + @ + domain

一些想法……

  • RFC 5322要求电子邮件地址采用local-part @ domain格式。 你省略了@domain部分。

  • RFC 5322进一步要求local-part是一个dot-atom ,由一个或多个由一个周期分隔dot-atom组成(例如foofoo.bar )。 单个atom是从可打印的US-ASCII字符的US-ASCII(7位)字符集中提取的以下字符中的一个或多个的序列,不包括“特殊”:表示大写/小写字母,数字,和人物

     ! # $ % & ' * + - / = ? ^ _ ` { | } ~ 

    根据RFC,您的电子邮件地址绝对不合法 – 方括号在语法中是“特殊”,因此不允许。

    如果你想使用dot-atom以外的东西作为你的local-part ,那么它必须是一个带quoted-string ,定义为引入双引号( " ),后跟quoted-content ,后跟引导- 双引号( " )。 quoted-content是零或多个可打印的US-ASCII字符,范围为​​0x21-0x7E,不包括"\ 。quoted quoted-content也可能包含无关紧要的”折叠空格“。 \ "并且可以通过使用\来转义它们来包含空格\ (例如,引号在引用的字符串中表示为\" ,反斜杠表示为\\ ,空格表示为\

希望这可以帮助!

编辑为注意:另一种选择是使用Exchange Server公开的Web服务直接通过Exchange而不是通过其SMTP前端发送邮件: http : //msdn.microsoft.com/en-us/library/bb204119 .aspx 。

有.Net的一些开源smtp客户端。 大多数都是旧的和陈旧的,但你可以根据它们滚动自己,例如DotNetOpenMail

因此,您似乎正在使用Diem Mail-to-Fax (PDF手册)。 请注意, 最简单的方法是使用“SMTP IETF Addressing”部分 – 这只需要fax.company.com的MX记录和SMTP兼容地址,例如:

  fax=0123456789/pn=User@fax.company.com 

然后,您就可以从任何客户端发送这些传真,而无需通过Exchange服务器。

RFAX方案需要Exchange服务器的特殊支持才能路由到传真机。 由于Outlook通过MAPI提交邮件,因此它可以支持这些额外的地址空间。 我不完全确定即使您可以让SmtpClient接受您的地址,Exchange也会知道在通过SMTP发送时如何处理它。

我怀疑要使用RFAX方案,您将不得不通过MAPI或Web服务提交电子邮件,因为它不是开始时的SMTP地址。