Могу ли я отключить проверку адреса электронной почты в System.Net.Mail?

Я пытаюсь связаться с программным обеспечением факс-сервера по электронной почте. Факс-сервер будет принимать форматированные сообщения 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;
        }
    }
}

person Chris Gill    schedule 02.06.2011    source источник
comment
Разместите свой текущий код. Вы, наверное, неправильно его выставили. Для вашего теста Outlook также нужен действующий адрес электронной почты.   -  person Henk Holterman    schedule 02.06.2011
comment
Нет - это адрес электронной почты, не соответствующий RFC. Я хочу отправить на [RFax: User @ / FN = 0123456789], включая квадратные скобки   -  person Chris Gill    schedule 02.06.2011
comment
Если адрес каждый раз один и тот же, вы можете просто настроить псевдоним электронной почты на своем (обменном?) Сервере и перенаправить его на тупой адрес.   -  person ericvg    schedule 02.06.2011
comment
Адрес электронной почты зависит от номера факса. Не вариант   -  person Chris Gill    schedule 02.06.2011


Ответы (4)


Нет, вы не можете отключить эту проверку.

РЕДАКТИРОВАТЬ:

Немного посмотрев на это, кажется, что следующий фрагмент кода был бы возможным обходным путем:

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, который не анализирует / не проверяет предоставленный адрес.

Второй трюк - разделить «адрес факса» на знак @ и передать его как две части (пользователь и домен). Это необходимо, потому что SMTP To-header позже записывается платформой с использованием свойства MailAddress.Address, и это свойство возвращает user + @ + domain.

person Mårten Wikström    schedule 02.06.2011
comment
MailAddress имеет внутренний конструктор, который позволяет пропустить часть проверки. Если небольшая часть взлома допустима, это может решить вашу проблему. - person Mårten Wikström; 02.06.2011
comment
Мммм - могло быть больше похоже на это. я посмотрю - person Chris Gill; 02.06.2011
comment
Я принял этот ответ, поскольку он близок к тому, чем я закончил. Я опубликовал свою версию кода как правку к моему вопросу - person Chris Gill; 03.06.2011

Некоторые мысли ...

  • RFC 5322 требует, чтобы адрес электронной почты был в форме local-part @domain. Вы пропустили часть @domain.

  • RFC 5322 дополнительно требует, чтобы локальная часть была dot-atom, состоящий из 1 или более atoms, разделенных одной точкой (например, foo или foo.bar). Индивидуальный atom представляет собой последовательность из 1 или более следующих символов, взятых из набора символов US-ASCII (7-бит) печатаемых символов US-ASCII, за исключением «специальных»: означающих буквы верхнего / нижнего регистра, цифры, и персонажи

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

    Согласно RFC, ваш адрес электронной почты является абсолютно недопустимым. Квадратные скобки являются "особенными" в грамматике и, следовательно, недопустимы.

    Если вы хотите использовать в качестве local-part что-то другое, кроме dot-atom, тогда это должна быть quoted-string, определенная как вводная двойная кавычка ("), за которой следует quoted-content, за которой следует заключительная двойная кавычка ("). . quoted-content - ноль или более печатаемых символов US-ASCII в диапазоне 0x210x7E, за исключением " и \. quoted-content также может содержать незначительные «сворачивающиеся пробелы». \, " и пробелы могут быть включены путем экранирования их с помощью \ (например, кавычки представлены в строке в кавычках как \", обратная косая черта как \\ и пробелы как \<sp>.

Надеюсь это поможет!

Отредактировано для примечания. Другой вариант - отправить почту напрямую через Exchange, а не через интерфейс SMTP, используя веб-службы, предоставляемые сервером Exchange: http://msdn.microsoft.com/en-us/library/bb204119.aspx.

person Nicholas Carey    schedule 02.06.2011
comment
OP знает, что адрес не соответствует требованиям, и говорит, что факс-сервер требует этого несовместимого формата, поэтому это не совсем полезный ответ. - person Davy8; 02.06.2011
comment
Конечно: вы не читали мой ответ. Чтобы сделать его совместимым с RFC, вам необходимо отформатировать адрес как quoted-string: "[RFax:User@/FN=0123456789]". "foo"@bar.com [email protected] семантически идентичны целевому MTA. Однако исходный адрес OP все еще нуждается в домене для его отправки. - person Nicholas Carey; 02.06.2011
comment
Я не уверен, что это действительно ответ на мой вопрос, поскольку я не могу переопределить формат адреса, который ожидает факс-сервер. Я посмотрю на веб-сервисы, хотя - person Chris Gill; 03.06.2011

Есть несколько клиентов smtp с открытым исходным кодом для .Net. Большинство из них старые и устаревшие, но вы можете просто создать на их основе свои собственные, например DotNetOpenMail

person ericvg    schedule 02.06.2011

Итак, похоже, вы используете Diem Mail-to-Fax (руководство в формате PDF). Обратите внимание, что самый простой способ сделать это - использовать раздел «Адресация SMTP IETF», для которого просто потребуется запись MX для fax.company.com и SMTP-совместимые адреса, такие как:

 fax=0123456789/[email protected]

После этого вы сможете отправлять эти факсы с любого клиента без необходимости проходить через сервер Exchange.

Схема RFAX требует специальной поддержки со стороны вашего сервера Exchange для маршрутизации к факсимильному аппарату. Поскольку Outlook отправляет почту через MAPI, он может поддерживать это дополнительное адресное пространство. Я не совсем уверен, что даже если вы сможете заставить SmtpClient принять ваш адрес, этот Exchange будет знать, что с ним делать, когда он будет доставлен через SMTP.

Я подозреваю, что для использования схемы RFAX вам придется отправить электронное письмо через MAPI или веб-службы, поскольку это изначально не SMTP-адрес.

person Mark Brackett    schedule 01.03.2016