Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EmailAttribute is not validating correctly in a ViewModel from ASP.NET Core

This is a field located in my viewmodel:

[Required(ErrorMessage = "Email is missing."), EmailAddress(ErrorMessage = "Email is not valid.")]
public string Email { get; set; }

(EmailAddress is from the EmailAddressAttribute.EmailAddressAttribute() type)
This is the relevant part from the HTML:

<div>
    <label for="inputEmail">EMAIL</label>
    <input id="inputEmail" ng-model="email" asp-for="Email" class="form-control" />
</div>
<div>
    <span asp-validation-for="Email" class="text-danger"></span>
</div>

When I type myemail in the email text box, it will say

Email is invalid

However, when typing myemail@email, it will be viewed as correct by the view-model (only on the front-end).

public async Task<JsonResult> Register([FromForm]VisitViewModel vm)

Casting like this properly puts the ModelState on invalid and rejects the email, so that part is okay.

According to this answer though, the frontend should indicate this as invalid

Can anybody explain what is happening here? I'm at an absolute loss.

like image 863
Matthew Avatar asked Jun 03 '16 08:06

Matthew


People also ask

Which of the following errors from the subsystem is represented by model state?

Model state represents errors that come from two subsystems: model binding and model validation. Errors that originate from model binding are generally data conversion errors.

How can use client side validation in asp net core?

The ASP.NET core includes unobtrusive client-side validation libraries, which makes it easier to add client side validation code, without writing a single line of code. In the previous tutorial on server side validation, we looked at how data annotations attributes are used by the Model Validator to validate the Model.


1 Answers

There are inconsistencies in the way emails are validated between client and server.

Client side

jQuery Validation uses a regular expression defined in the HTML standard. According to that expression, email@email is a valid email address.

Server side

The .Net EmailAddressAttribute has it's own regular expression, which you can find here. According that that expression, email@email is an invalid email address.

But it gets even more confusing! If you're creating a .Net Core app, targeting cross platform uses the CoreFX version of the attribute which doesn't appear to use a regular expression at all. According to that method, email@email is a valid email address.

You see it for yourself by switching around values in the project.json of a Core Console App:

public static void Main(string[] args)
{
    var attr = new EmailAddressAttribute();
    var email = "email@email";
    var isValid = attr.IsValid(email); // false with "net452", true with "netcoreapp1.0"
}

What you can do

The quickest fix that I can think of would be to change the regular expression in the jQuery Validate email method to match the one from .Net, or create your own validation method to add to it which checks for this particular case.

You can also just fallback on returning errors from the server which would show them a validation message for whatever is wrong with the ModelState. It wouldn't be a real-time error but they would still get a nice message to deal with the improper email.

like image 143
Will Ray Avatar answered Sep 18 '22 12:09

Will Ray