8

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

这是我的问题 - System.Net.Mail System.FormatException: The specified string is not in the form required for an e-mail address.由于我尝试发送到的电子邮件地址的格式而引发异常

有什么方法可以关闭/更改此验证,因为电子邮件地址可能不符合 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;
        }
    }
}
4

4 回答 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不解析/验证提供的地址的内部构造函数。

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

于 2011-06-02T16:04:41.993 回答
2

一些想法...

  • RFC 5322要求电子邮件地址的格式为local-part@domain。您已经省略了@domain部分。

  • RFC 5322进一步要求本地部分是 a dot-atom,由 1 个或多个atoms由单个句点分隔(例如foofoo.bar)组成。个人atom是从可打印的 US-ASCII 字符的 US-ASCII(7 位)字符集中提取的 1 个或多个以下字符的序列,不包括“特殊”:表示大写/小写字母、数字和那些角色

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

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

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

希望这可以帮助!

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

于 2011-06-02T17:29:26.050 回答
1

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

于 2011-06-02T16:19:13.287 回答
0

因此,您似乎正在使用Diem Mail-to-Fax(PDF 手册)。请注意,执行此操作的最简单方法是使用“SMTP IETF 寻址”部分 - 它只需要一个传真公司的 MX 记录和符合 SMTP 的地址,例如:

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

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

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

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

于 2016-03-01T16:34:19.193 回答