.Net Framework 4.7.2 EmailAddressAttribute validation
Posted on May 17, 2018 in dotnet
Consider the following test, which has been passing on every framework version before 4.7.2:
Upgrade to 4.7.2 and that test fails, because "foo@bar" is considered a valid email address. How come? It turns out that
EmailAddressAttribute has two different validation mode. One is a very crude validation method which is described in this 2015 CoreFx issue as:
We had earlier decided that the purpose of EmailAddressAttribute was just to prevent "fat-fingering" errors - not to prevent every possible invalid email address. The algorithm we currently use is "must have at least one '@' and the '@' cannot be at the start or the end." The above passes that test (along with many other potential errors). Suggest we don't fix this, but feel free to chime in.
The other is a more complete validation method using a regular expression. It is that regular expression-based method that is used by default, prior to Framework 4.7.2. Now, Framework 4.7.2 contains a lot of changes aiming at align with .NET Core. For some reason, the regular expression here is a problem (see below), and is not used by default anymore.
System.ComponentModel.DataAnnotations.AppSettings class contains code looking like:
disableRegEx = BinaryCompatibility.Current.TargetsAtLeastFramework472;
Thus disabling regular expressions on Framework 4.7.2 and falling back to the crude validation. But... there is a trick: it is possible to force the regular expression back, by adding the following app setting:
<add key="dataAnnotations:dataTypeAttribute:disableRegEx" value="false"/>
And, woot, the test passes again!
Yes, but... why?
Using a magic trick without understanding it is... annoying. Luckily, a bit of googling can help understand what is going on. In fact, this change (considered minor) is documented in Microsoft's aspnet-472-compat-doc.md document which states:
Staring with .NET Framework 4.7.2, this config switch is set to true by default to further reduce secure vulnerability for web applications that target .NET Framework 4.7.2 and above.
So, the reason for the change is security. And, the recommendation is to use the app setting to restore the expected behavior.