Client side validation for my email address - asp.net-mvc

I have this attribute in my view model:
[CustomRequired, EmailRegex]
[Display(Name = "KeepInformedPersonMail", ResourceType = typeof (UserResource))]
public string Email { get; set; }
The EmailRegex is like this:
public class EmailRegexAttribute : RegularExpressionAttribute
{
private const string EmailPattern =
#"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
public EmailRegexAttribute()
: base(EmailPattern)
{
ErrorMessageResourceType = typeof(UserResource);
ErrorMessageResourceName = "InvalidEmail";
}
}
It works for server side validation but no client side.
If I replace the EmailRegex with the following it works both client and server side validation:
[CustomRequired]
[RegularExpression(#"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Please enter a valid e-mail adress")]
[Display(Name = "KeepInformedPersonMail", ResourceType = typeof (UserResource))]
public string Email { get; set; }
Does someone can explain me how can I proceed to have client and server side validation for my initial EmailRegex?
Thanks.

This answer should solve your problem

Related

Validating a Login with Email or Phone and Password

In my ASP.net core project I have a Login page with 2 property as
public class loginModel
{
public string EmailOrPhoneNumber { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
}
I just want make login page which can login with email or phonenumber but I don't know how validate this property (validate email and phoneNumber)
Any suggestion?
You can create a custom validate attribute like this and put your validation logic in it :
public class EmailOrPhoneNumberAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string valueAsString = value.ToString();
const string emailRegex = #"^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
bool isValidEmail = Regex.IsMatch(valueAsString, emailRegex);
if (isValidEmail)
{
return ValidationResult.Success;
}
const string usaPhoneNumbersRegex = #"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}";
bool isValidPhone = Regex.IsMatch(valueAsString, usaPhoneNumbersRegex);
if (isValidPhone)
{
return ValidationResult.Success;
}
return new ValidationResult("Invalid email or phone number.");
}
}
Usage will be simply like this :
public class Person
{
public string Name { get; set; }
[EmailOrPhoneNumber]
public string EmailOrPhoneNumber { get; set; }
}
Note that ModelState will automatically take cares of validation.
You may validate your field using a regular expression
a. Define your regex (The Email regex is the one I use and phone regex is from PhoneAttribute)
const string RGX_Email = "^(?("")("".+?(?<!\\)""#)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])#))" +
"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$";
const string RGX_Phone = #"^(\+\s?)?((?<!\+.*)\(\+?\d+([\s\-\.]?\d+)?\)|\d+)([\s\-\.]?(\(\d+([\s\-\.]?\d+)?\)|\d+))*(\s?(x|ext\.?)\s?\d+)?$";
b. Then you can validate using the regular expression attribute
[RegularExpression($"{RGX_Email}|{RGX_Phone}", ErrorMessage = "Invalid Phone or Email")]
public string EmailOrPhoneNumber { get; set; }
And on server side, you may use a code similar to this to handle your model
if(String.IsNullOrEmpty(model.EmailOrPhoneNumber))
return error message;
if(model.EmailOrPhoneNumber.Contains("#"))
return SignInWithEmail(model);
else return SignInWithPhone(model);

ASP.NET MVC 5: EmailAddress attribute custom error message

In register form I use EmailAddress attribute to validate user email.
public class RegisterViewModel
{
[Required(ErrorMessage = "Pole wymagane")]
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string Email { get; set; }
}
Is there any chance to show what is wrong with email address if validation fails? For example 'oops, I see that your email address contains whitespace'
You have to add another validation for that. Example using [RegularExpression]
public class RegisterViewModel
{
[Required(ErrorMessage = "Pole wymagane")]
[RegularExpression(#"^\S*$", ErrorMessage = "Email Address cannot have white spaces")]
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string Email { get; set; }
}
You can define your own regular expression for email:
// built-in [EmailAddress] does not allow white spaces around email
public const string EmailValidationRegEx = #"^\s*\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*\s*$";
Note: I have just added white spaces around the existing .NET regex pattern for email match:
"^\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$"
Now you can use this new regex pattern instead of [EmailAddress] attribute:
public class RegisterViewModel
{
private string _email;
[Required(ErrorMessage = "Pole wymagane")]
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[RegularExpressionWithOptions(EmailValidationRegEx, ErrorMessage = "Invalid email")]
public string Email
{
get
{
if (!string.IsNullOrEmpty(_email))
{
return _email.Trim();
}
return string.Empty;
}
set
{
_email = value;
}
}
}
Note that I have modified the getter and return _email.Trim(), this ensures that we always get rid of extra white spaces before using the email value.

Using resources with error message in mvc

I want to get error message from resources. When i tried codes below i take that error:"An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type" What can i do ?
public class UserLoginModel
{
[Required(ErrorMessage =Resources.PageResources.enterYourEmail)]
public String Email{ get; set; }
[Required(ErrorMessage =Resources.PageResources.enterPassword)]
public String Password { get; set;
}
Try this
[Required(ErrorMessageResourceType = typeof(Resources.Resources),
ErrorMessageResourceName = "enterYourEmail")]
public String Email{ get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources),
ErrorMessageResourceName = "enterPassword")]
public String Password { get; set;
A similar approach but without the problem related by #Ali Baig about to have to add ErrorMessage = null to make it work.
[Required(ErrorMessageResourceName = nameof(Resources.Global_Errors.ReqName),
ErrorMessageResourceType = typeof(Resources.Global_Errors))]

Asp.Net MVC 3: Compare validator on subproperties?

For the edition of my user, I've to ensure that password and the repeat password are the same. I found the "Compare" validator, but I cant make it work.
my model looks like the following:
public class UserEditionViewModel{
[Compare("User.Password")]
public String RepeatPassword{get;set;}
public User User {get;set;}
public List<Language> AvailableLanguages{get;set;}
public List<Country> AvailableCountries{get;set;}
}
and the User model:
public class User{
[Required]
public String Name{get;set;}
//lot of other properties omitted...
[RegularExpression(#"(|.*(?=.{6,})(?=.*\d)(?=.*[a-zA-Z]).*)", ErrorMessageResourceType = typeof(LocalizationResources.Views.User.Edition), ErrorMessageResourceName = "InvalidPassword")]
//And I've localization attributes
public String Password{get;set;}
}
In the view I only have something like:
#Html.PasswordFor(m=>m.User.Password)
#Html.PasswordFor(m=>m.RepeatPassword)
But I ever get this error, even if the two items are matching:
'Password repeat' and 'User.Password' do not match.
I also got this error when I'm doing the client validation.
For me the most obvious error is that it can't found the subproperty. Am I right? If yes, how to avoid this behavior. If no, what can be the problem???
A workaround would be to create another property on the UserEditionViewModel that reads and writes to the inner Userclass.
public String UserPassword
{
get
{
return User.Password;
}
set
{
User.Password = value;
}
}
And then bind your controls to that property instead, and change the [Compare("User.Password")] to [Compare("UserPassword")]. I'm not really sure if it can be done any other way short of writing your own custom validator.
I had a similar problem and ended up writing my own validator for this which turned out surprisingly complex since you can have any layer of inheritance to get to your property. If there is another solution, I'd be equally happy to know about it.
You can try this which worked for me..
In your project -> References-> right click->Manage NuGet Packages..
install DataAnnotationsExtensions package.
Then validate your model as follows:
public class Employee
{
[Required(ErrorMessage="Name field Required")]
public string name { get; set; }
[Required(ErrorMessage = "Name field Required")]
public string email { get; set; }
[Required(ErrorMessage = "Depatrment field Required")]
public string department { get; set; }
[Required(ErrorMessage = "Designation field Required")]
public string designation { get; set; }
public string phone { get; set; }
[Required(ErrorMessage = "Password field Required")]
[Display(Name="Password")]
public string password { get; set; }
[Required(ErrorMessage="Confirm password")]
[Display(Name="Re-type Password")]
[EqualToAttribute("password",ErrorMessage="Password miss-match")]
public string Re_Password { get; set; }
}
That's it

asp mvc validation specific to controllers action?

Can the built in ASP MVC validation be made to behave differently for different actions of a same controller ? For example I have a user controller and it has actions like create, edit and other actions. So in model user the attribute Username is being validated for its uniqueness. If there is an user present with the same username, it throws and error username already present. So using the same validator for edit action throws an error "username already present" while editing an user. Can anybody tell me if there is a way to do solve this problem? I am pasting my validator code for reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Models
{
[MetadataType(typeof(AdmiUserMetadata))]
public partial class AdminUser
{
public class AdmiUserMetadata
{
[Required(ErrorMessage = "Required Field")]
public string Id { get; set; }
[Required(ErrorMessage = "Required Field")]
[RegularExpression("[\\S]{6,}", ErrorMessage = "Must be at least 6 characters.")]
[Username(ErrorMessage = "Username already taken")]
public string Username { get; set; }
[Required(ErrorMessage = "Required Field")]
[RegularExpression("[\\S]{6,}", ErrorMessage = "Must be at least 6 characters.")]
public string Password { get; set; }
[Required(ErrorMessage = "Required Field")]
public string Name { get; set; }
[Required(ErrorMessage = "Required Field")]
[RegularExpression("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*#[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$", ErrorMessage ="Invalid E-mail ID")]
public string Email { get; set; }
[Required(ErrorMessage = "Required Field")]
[RegularExpression("(Active|Disabled)", ErrorMessage = "Select the status of User")]
public string Status { get; set; }
[Required(ErrorMessage = "Required Field")]
[RegularExpression("^[1-9]", ErrorMessage = "Select the group of User")]
public string Group { get; set; }
}
}
public class UsernameAttribute : ValidationAttribute
{
IUserRepository _repository = new UserRepository();
public override bool IsValid(object value)
{
if (value == null)
return true;
if (_repository.IsUsernamePresent((string)value))
{
return false;
}
return true;
}
}
}
What you are validating is a business rule.
No two users can have the same username.
I would have a User service that enforces this rule on creation/edit. Attributes are best suited for input validation. (eg Is the integer non-negative? A valid email address? etc)
I don't see how this can be done if a class has attributes that determines validation. This obviously works for most projects, but for me this is also not working out.
If you need to attach different sets of validation rules check out http://fluentvalidation.codeplex.com/. I tried it and liked it.
It doesn't handle client validation. I dropped that because I have ajax calls in most parts and that feels a bit like client validation.

Resources