EmailAddressAttribute incorrectly categorizing French e-mail address as invalid
Asked Answered
H

5

12

I'm using the EmailAddressAttribute for use on my model.

The problem is when I use a (perfectly valid) e-mail address of

ó[email protected]

it says it is invalid.

Model:

public class ForgotPasswordViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    public CmsContentPagesModel PageCmsContent { get; set; }

    public CmsContentPagesModel PageCmsContentInfoIcon { get; set; }
    public CmsContentPagesModel PageCmsContentRightPanel { get; set; }
}

Is this an issue with the attribute, or do I somehow have to specify that French e-mails are okay?

Input box as rendered:

<div class="col-md-5">
     <input class="form-control" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" type="text" value="" />
     <span class="field-validation-valid text-danger" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>

I've also extracted the regex from the client-side validation, the following line returns false

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( 'ó[email protected]' );

which apparently complies with this standard even though the demo for this exact code also fails.

Hi answered 10/2, 2017 at 16:47 Comment(14)
The EmailAddressAttribute uses the following Regex to validate the value: source. The email address you provide matches the regex, so it should be valid. Can you post the c# model? By the way, I recently wrote a blog post about validating email address .NETBasilius
@Basilius - That's good news, I've added the model.Hi
check this thread: #12181253Ansell
The validation fails at the client-side using unobtrusive validation scripts? Any customization done in validation rules in the script for email or any other field which can cause conflict of rules? How you submit the form to the server, using AJAX or direct submit?Hardly
Maybe you are hitting character codifications issues in the email text like treating UTF-8 as ISO-8859-1 or vice versa. Are you sure you are not trying to validate something like "óscar" or "xF3scar"...?Haematinic
How does email input looks like?Bicapsular
@ChetanRanpariya - Yes, it fails client side and the jquery.validate.unobtrusive.js library is loaded. I've added the input box HTML to the questionHi
I'm not sure if ó char can even be in an email address. Since it is non-ascii and everything.Habitude
@Habitude it is valid.. ASCII is old.. Unicode is new.. Email/URL can now contain multi language charactersPassacaglia
But the client-side expression uses the pure ASCII range a-zA-Z which would appear to be a bug.Royston
Here is the commit in jquery validation library where they changed email regex to one from the spec: github.com/jquery-validation/jquery-validation/commit/…. Previous regex they used was actually working fine for your case so you might use it. You can also see that "If you don't like the implementation, report an issue against the HTML5 spec.". This regex is from spec itself, but I'm not sure it is correct because spec says that "A valid e-mail address is a string ... the character set for which is Unicode". Anyway you have to use custom regex.Tincture
@Tincture - That's right! I've raised an issue on the project. Though I may as well use the previous regex until resolved.Hi
Well they most likely will ask you to raise issue for spec itself, because regex is from spec even though it is conflicting with the text. Funny that in that same commit they changed unit tests with unicode emails to treat them as invalid :)Tincture
@Hi Unicode mentioned in specification is irrelevant. Check this specification issue.Bicapsular
B
5

You need to set custom regular expression for email validation in jQuery Validation Plugin:

$.validator.methods.email = function( value, element ) {
  return this.optional( element ) || /INSERT_YOUR_REGEX_HERE/.test( value );
}

jQuery Validation Plugin uses RFC 5322 Internet Message Protocol specification definition of a valid email. This definition disallows use of a non latin letters in local-part. Relevant excerpt from project's README.md:

IMPORTANT NOTE ABOUT EMAIL VALIDATION. As of version 1.12.0 this plugin is using the same regular expression that the HTML5 specification suggests for browsers to use. We will follow their lead and use the same check. If you think the specification is wrong, please report the issue to them. If you have different requirements, consider using a custom method. In case you need to adjust the built-in validation regular expression patterns, please follow the documentation.

Email address internationalization is defined by another specification - RFC 6530 Overview and Framework for Internationalized Email. It uses term SMTPUTF8. Check Email address page on Wikipedia for more information and support details.

Bicapsular answered 13/2, 2017 at 12:36 Comment(1)
I went with this and used the regex from the used on the server by the EmailAddressAttribute so I can be sure client + server will agree. In addition I started a bug over on the project so at least those involved are aware. The elegance to this answer, meaning I can just include the code in a new .js file alongside the original is why I've awarded this bounty. Many thanks @Leonid Vesilyev, keep it up.Hi
V
2

As you can see in the regex:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( 'ó[email protected]' );

the ó character is not in the range

you can use the following regex:

/^[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-](?:[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-]{0,61}[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-])?(?:\.[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-](?:[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-]{0,61}[a-zA-Z0-9 àâäèéêëîïóôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ.!#$%&'*+\/=?^_`{|}~-])?)*$/

And you can also creat a custom Attribute as FrenchEmailAddress in order to validate the property by using the regex I posted in the custom attribute

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FrenchEmailAddressAttribute : ValidationAttribute
{
    public string Pattern { get; set; }
    public RegexOptions Options { get; set; }

    public FrenchEmailAddressAttribute(string pattern, RegexOptions options = RegexOptions.None)
    {
        Pattern = pattern;
        Options = options;
    }

    public override bool IsValid(object value)
    {
        return IsValid(value as string);
    }

    public bool IsValid(string value)
    {
        return string.IsNullOrEmpty(value) ? true : new Regex(Pattern, Options).IsMatch(value);
    }
}
Valid answered 13/2, 2017 at 12:9 Comment(2)
You'd have to change the other A-Z ranges too.Royston
@HenkHolterman thanks for mentioning that, I edited my answerValid
N
1

Context of the problem is very important to identifying the correct answer. In most scenarios, it is better to stick with the simple solution:

^\S+@\S+\.\S+$

This regex will run the risk of matching some invalid email addresses, but will enforce the general structure. Ideally you would be able to an email confirmation box or a confirmation email perform a second round of validation, but even without the additional validations, this should still catch the majority of unintentionally invalid entries.

Nesline answered 14/2, 2017 at 1:6 Comment(0)
R
-1

System.ComponentModel.DataAnnotations.EmailAddressAttribute class using this regex.

const string pattern = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";

and validating your email address like said @ThomasRainero

Raimondo answered 13/2, 2017 at 15:1 Comment(0)
S
-4

I don't know how you validate the email address, I tried to validate your email like a string and my variable isValid has been validated with true.

EmailAddressAttribute testEmailAddress = new EmailAddressAttribute();
bool isValid = testEmailAddress.IsValid("ó[email protected]");

Hope these is useful.

Scorper answered 10/2, 2017 at 17:1 Comment(1)
@MarcelN.: It is a valid non-repro statement from before the question was extended.Royston

© 2022 - 2024 — McMap. All rights reserved.