'Validating an email string in .net using EmailAddressAttribute, but not on an attribute

I want to be able to do this:

string email = "[email protected]";
bool isValid = IsValidEmail(email);
//returns true

...but use the logic Microsoft has already given us in EmailAddressAttribute.

There are hundreds of good and bad implementations of IsValidEmail out there, and I don't want to add my own, when I can use something, Microsoft has already thought about. It stands to reason, that they will do a better job than me.

In recent ASP.Net versions, we have System.ComponentModel.DataAnnotations, which provides us with the excellent EmailAddressAttribute, that lets us decorate our models like this:

public class SomeModel
{
    [EmailAddress]
    public string Email { get; set; }
}

The class is sealed, so I cannot call EmailAddressAttribute.IsValid()

Is there a good way I can utilize what Microsoft has already done? Is there a method somewhere in the .Net framework, that let's me test strings against data-annotations, that I have overlooked?

Something along the lines of..:

var emailChecker = new DataAnnotationsChecker<EmailAddressAttribute>();
string email = "[email protected]";
bool isValid = emailChecker.IsValid(email);
//returns true

If you cannot imagine why I would want this, think about getting a List and want to check which ones are valid emails.



Solution 1:[1]

EmailAddressAttribute IS NOT SAFE !!!

They claim that .NET is safe and secure! But if you don't read the source code, you will be misled and make mistakes!

The following code, are you serious???

https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs,c3ae85dfd8a9f58c

public override bool IsValid(object? value)
{
    if (value == null)
    {
        return true;
    }

    if (!(value is string valueAsString))
    {
        return false;
    }

    // only return true if there is only 1 '@' character
    // and it is neither the first nor the last character
    int index = valueAsString.IndexOf('@');

    return index > 0 &&
           index != valueAsString.Length - 1 &&
           index == valueAsString.LastIndexOf('@');
}

See how the people at Microsoft responded. They just leave the safety issues alone and claim to have designed such a trap for us to step on!

https://github.com/dotnet/runtime/issues/65968

Solution 2:[2]

Use MailAddress
This is a useful technique for reading and validating an email address, even from 'Elmer Fudd <[email protected]>' styled inputs (such as those copy-pasted from email clients).

private string? ExtractEmailAddress(string raw)
{
    try
    {
        var address = new MailAddress(raw);
        return address.Address;
    }
    catch (Exception)
    {
        return null;
    }
}

I also use [EmailAddress] attribute to indicate the required type to API documentation.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Joe Huang
Solution 2 Peter L