Can I turn off the email address validation in System.Net.Mail?
Asked Answered
A

4

8

I'm trying to talk to Fax server software using an email. The fax server will accept formatted SMTP mails and covert them to faxes and send them to the fax number defined in the to address. This has been manually tested by sending an email from Outlook via the same server.

Here's my problem - System.Net.Mail is throwing an System.FormatException: The specified string is not in the form required for an e-mail address. exception due to the format of the email address that I am trying to send to

Is there any way I can turn off/change this validation because the email address may not be RFC compliant but it will work if the email gets sent

i.e. I want to send to [RFax:User@/FN=0123456789] including the square brackets

You can send to this as an e-mail address in Outlook

Cheers Chris

EDIT

This is a cut-down version of the class I'm using to bypass the validation. There are two ways of doing it - one by overriding the constructor and setting the internal attribute directly, the other using an internal constructor. They have slightly different effects if there are spaces in the email address

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;
        }
    }
}
Astounding answered 2/6, 2011 at 15:47 Comment(4)
Post your current code. You're probably setting it wrong. Your outlook test needed a valid email address as well.Jaimie
Nope - its a RFC non-compliant e-mail address. I want to send to [RFax:User@/FN=0123456789] including the square bracketsAstounding
If the address is the same each time, you could just setup a email alias on your (exchange?) server and have it forward to the goofy address.Klayman
Email address varies as fax number varies. Not an optionAstounding
F
7

No, you cannot turn that validation off.

EDIT:

After looking in to this a little bit it seems as if the following code snippet would be a feasible workaround:

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

There are two tricks here. The first one is to use the internal MailAddress constructor that doesn't parse/validate the supplied address.

The second trick is to split "fax address" on the @-sign and pass it as two parts (user and domain). This is needed because the SMTP To-header is later written by the framework using the MailAddress.Address property, and that property returns user + @ + domain.

Fike answered 2/6, 2011 at 16:4 Comment(3)
MailAddress has an internal constructor that allows you to skip the validation part. If a little bit of hacking is acceptable then that might solve your problem.Forta
Mmmh - could be more like it. I'll have a lookAstounding
I've accepted this answer as it is close to what I ended up doing. I've posted my version of the code as an edit to my questionAstounding
A
2

Some thoughts...

  • 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>.

Hope this helps!

Edited to Note: Another option would be to send the mail directly via Exchange rather than via its SMTP front end, using the web services exposed by the Exchange Server: http://msdn.microsoft.com/en-us/library/bb204119.aspx.

Alvaalvan answered 2/6, 2011 at 17:29 Comment(3)
The OP is aware the the address is non-compliant, and is saying that the fax server requires this non-compliant format, so this isn't really a helpful answer.Eyewitness
Sure it is: you didn't read my answer. To make it RFC-compliant, you need to format the address as a quoted-string: "[RFax:User@/FN=0123456789]". "foo"@bar.com [email protected] are semantically identical to the destination MTA. OPs original address still needs a domain to send it to, though.Alvaalvan
I'm not sure this really answers my question as I can't redefine the format of the address that the fax server is expecting. I will look into the web services thoughAstounding
K
1

There are some open source smtp clients out there for .Net. Most are old and stale, but you could just roll your own based on them, such as DotNetOpenMail

Klayman answered 2/6, 2011 at 16:19 Comment(0)
H
0

So, it appears you're using Diem Mail-to-Fax (PDF manual). Note that the easiest way of doing this, is using the "SMTP IETF Addressing" section - which would simply require an MX record for fax.company.com, and SMTP compliant addresses such as:

 fax=0123456789/[email protected]

You would then be able to send these faxes from any client, without having to go through your Exchange server.

The RFAX scheme requires special support from your Exchange server to route to the fax machine. Since Outlook submits mail via MAPI, it can support this additional address spaces. I'm not entirely sure that even if you can get the SmtpClient to accept your address, that Exchange will know what to do with it when delivered via SMTP.

I suspect that to use the RFAX scheme, you're going to have to submit the email via MAPI or Web Services, since it's not an SMTP address to begin with.

Hypophyge answered 1/3, 2016 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.