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

8
我正在尝试使用电子邮件与传真服务器软件进行通信。 传真服务器将接受格式化的SMTP邮件并将其转换为传真并将其发送到定义在收件人地址中的传真号码。 通过相同的服务器从Outlook发送电子邮件进行了手动测试。
这是我的问题-System.Net.Mail会抛出一个“System.FormatException:指定的字符串不符合电子邮件地址所需的格式。”异常,原因是我要发送到的电子邮件地址的格式不正确。
是否有任何方法可以关闭/更改此验证,因为电子邮件地址可能不符合RFC规范,但如果发送电子邮件,则它将起作用。
即。 我想发送到[RFax:User @ / FN = 0123456789],包括方括号
您可以在Outlook中将其作为电子邮件地址发送
干杯 克里斯
编辑
这是我用于绕过验证的类的简化版本。 有两种方法可以做到这一点-一种是重写构造函数并直接设置内部属性,另一种是使用内部构造函数。 如果电子邮件地址中有空格,它们会产生略微不同的效果。
using System;
using System.Reflection;

namespace Mail
{
    public class UnverifiedEmailAddress : System.Net.Mail.MailAddress
    {
        /// <summary>
    /// Constructor to bypass the validation of MailAddress
    /// </summary>
    /// <param name="address">Email address to create</param>
    public UnverifiedEmailAddress(string address)
        : base("a@a")
    {
        FieldInfo field = typeof(System.Net.Mail.MailAddress).GetField("address", BindingFlags.Instance | BindingFlags.NonPublic);
        field.SetValue(this, address);
    }

    /// <summary>
    /// Static method to create an unverifed email address bypassing the address validation
    /// </summary>
    /// <param name="address">Email address to create</param>
    /// <param name="displayName">Display name for email address</param>
    /// <returns></returns>
    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;
        }
    }
}

2
发布你当前的代码。你可能设置错了。你的Outlook测试也需要一个有效的电子邮件地址。 - H H
不行 - 这是一个不符合RFC标准的电子邮件地址。我想发送到[RFax:User @ / FN = 0123456789],包括方括号。 - Chris Gill
1
如果地址每次都相同,您可以在您的(Exchange?)服务器上设置电子邮件别名,并将其转发到该怪异地址。 - ericvg
电子邮件地址随传真号码而异。这不是一个选项。 - Chris Gill
4个回答

7

不,您无法关闭该验证。

编辑:

在进一步研究后,以下代码片段似乎是可行的解决方法:

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]" }) }
};

这里有两个技巧。第一个是使用内部的MailAddress构造函数,该函数不会解析/验证提供的地址。
第二个技巧是在@符号处拆分“传真地址”,并将其作为两个部分(userdomain)传递。这是必需的,因为SMTP To-header稍后由框架使用MailAddress.Address属性编写,并且该属性返回user + @ + domain

2
MailAddress有一个内部构造函数,允许您跳过验证部分。如果可以接受一点黑客技巧,那么这可能会解决您的问题。 - Mårten Wikström
嗯,可能需要更改一下。我会看一下的。 - Chris Gill
我已经接受了这个答案,因为它接近我最终所做的事情。我已经将我的代码版本作为对我的问题的编辑发布了。 - Chris Gill

2
一些想法...
  • RFC 5322 requires that the email address be in the form local-part@domain. You've omitted the @domain portion.

  • RFC 5322 further requires that the local-part be a dot-atom, consisting of 1 or more atoms separated by a single period (e.g. foo or foo.bar). An individual atom is a sequence of 1 or more of the following characters drawn from the US-ASCII (7-bit) character set of printable US-ASCII characters, excluding 'specials': meaning Upper-/lower-case letters, digits, and the characters

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

    Per the RFC, your email address is absolutely not legal — square brackets are "specials" in the grammar and thus not allowed.

    If you want to use something other than a dot-atom as your local-part, then it must be a quoted-string, defined as a lead-in double-quote ("), followed by quoted-content, followed by a lead-out double-quote ("). quoted-content is zero or more printable US-ASCII characters in the range 0x21–0x7E, excluding " and \. quoted-content may also include insignificant "folding whitespace". \, " and whitespace may be included by escaping them with a \ (e.g., quotes are represented in the quoted string as \", backslashes as \\ and spaces as \<sp>.

希望这可以帮到你!

编辑说明:另一个选项是通过Exchange直接发送邮件,而不是通过其SMTP前端,使用Exchange服务器公开的Web服务:http://msdn.microsoft.com/en-us/library/bb204119.aspx


OP已经意识到地址不符合规范,并且表示传真服务器需要这种不符合规范的格式,因此这并不是一个有帮助的答案。 - Davy8
当然是可以的:你没有读我的回答。为了符合RFC标准,您需要将地址格式化为“引用字符串”:“[RFax:User@/FN=0123456789]”。 “foo”@bar.com和foo@bar.com在语义上与目标MTA相同。但是,OP的原始地址仍然需要一个域来发送它。 - Nicholas Carey
我不确定这真正回答了我的问题,因为我无法重新定义传真服务器所期望的地址格式。不过,我会研究一下 Web 服务。 - Chris Gill

1

有一些针对 .Net 的开源 SMTP 客户端可供使用。大多数都已经过时,但你可以基于它们自己编写一个,比如 DotNetOpenMail


0

看起来你正在使用Diem Mail-to-Fax(PDF手册)。请注意,最简单的方法是使用“SMTP IETF寻址”部分 - 这只需要为fax.company.com设置MX记录,并使用符合SMTP标准的地址:

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

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

RFAX方案需要Exchange服务器的特殊支持才能路由到传真机。由于Outlook通过MAPI提交邮件,因此它可以支持这些额外的地址空间。我不确定即使您可以让SmtpClient接受您的地址,当通过SMTP交付时,Exchange是否知道该怎么做。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接