You are a gifted teacher! I understand everything you say, you are very articulate on explaining them without making me feel like I'm stupid. I have this issue to create custom validation on one special field called cost centre based on SAP validation. I'm going to try this next Monday. Wished me luck!
This worked to me. //Validation attribute public class ValidEmailDomainAttribute :ValidationAttribute, IClientModelValidator { public string AllowedDomain { get; } public ValidEmailDomainAttribute(string AllowedDomain) { this.AllowedDomain = AllowedDomain; } public override bool IsValid(object value) { return (value as string).EndsWith(AllowedDomain); } public void AddValidation(ClientModelValidationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } context.Attributes.Add("data-val", "true"); context.Attributes.Add("data-val-ValidEmailDomain","Error: "+ ErrorMessage); context.Attributes.Add("data-val-AllowedDomain", AllowedDomain); } } //javascript in the view (function ($) { $.validator.addMethod('data-val-ValidEmailDomain', function (value, element, params) { debugger; value.slice() var domain = $(element).attr('data-val-AllowedDomain'); if (domain) { return value.slice(-1 * domain.length) === domain; } return false; }, function (params, element) { debugger; var msgCompare = $(element).attr('data-val-ValidEmailDomain'); if (!msgCompare) { msgCompare = 'Domain of email is not allowed.'; } return msgCompare; }); $.validator.unobtrusive.adapters.addBool('data-val-ValidEmailDomain'); })(jQuery); There is another example in the below link[1], I used it as reference ( but the article is in portuguese). [1] medium.com/@fulviocanducci/aspnet-core-valida%C3%A7%C3%A3o-customizadas-server-side-e-client-side-55a7972757d4
Thank you for the pointer, I missed this one too, yes index 1 would be null and an exception would be raised....but I noticed that I have EmailAddress DataAttribute on Email Property so test@ would be an invalid email address that the client-side validation would pickup and block posting it.
Hey, thank you once again for your detailed explanation. I guess you cannot do something similar to this if you are using a shared class library, can you? My models are stored in the class library adjacent to my web project. I have a reference from my web project to the class library but it will not allow me to use the custom attribute from the class library back to the web project. It's working to an extent as long as the custom validator is coming from the class library but since the custom validator is not in the web project, it's not showing the validation in red when I hit submit. But it's partially working as long as I have a "." in my input field which is what I did for validating only a domain name like "my.domain". I have to enter a "." in the input field or else it fails, I just wish the red validation would cooperate :/ Thanks.
This video concludes saying it works "just like any other validation attribute" that is not true. There is no client side validation, so the form must post before the attribute runs. That is problematic if the user has filled out form fields that depend on dynamic controls because they will lost their data.
Sir, When i am defining [ValidEmailDomain] attribute in RegisterViewModel class and press [ctrl .] then it is not recognising EmployeeManagement.Utilities namespace ?
If I have an integer type attribute but the value entered by the user is greater than the maximum value allowed for integers, how do I validate it and display a custom message?
How can you trigger the custom validation attribute on lost focus? I want my custom validation to work exactly like the EmailAddress or Required attribute
Hello Manish - Client side validation is covered in details in Parts 74 to 76. Here is the link to complete ASP.NET Core MVC tutorial. www.pragimtech.com/courses/asp-net-core-mvc-tutorial-for-beginners/
@@vinothdharmaraj7510 Taking into consideration that maybe you want 2 remote validations for the same field that is email, .net core doesnt let you add multiple remote attributes so, you could create a method IsEmailValid and check within if the email is in use or if the email match with domain "PREGIM.COM" like Lin mentioned here stackoverflow.com/questions/20329121/multiple-remote-validation-attribute-in-asp-net-mvc4. Hope it helps you Vinoth, Venkat I admire you everyday, thanks for giving us free education for future engineers or good programmers, regards..
Kudvenkat Sir, I have done exact replications of the steps that you have shown in video still my IsValid function is getting called only on click of Submit nor I have any compile time errors, what might be the reason? Can you please help?
Hi, to allow more than one domain you should pass an Array of string, and this is code source: for RegisterViewModel class: [RegisterEmailDomainValidation(AllowedDomain: new string[] {"gmail.com","hotmail.com"} ,ErrorMessage ="This email domain should be: gmail.com or hotmail.com")] public string Email { get; set; } --------------------------------------------------------------------------------------------------------------------------------------------------------- For ValideEmailAttribute class: public class ValideEmailAttribute : ValidationAttribute { private readonly string[] AllowedDomain; public ValideEmailAttribute (string[] AllowedDomain) { this.AllowedDomain = AllowedDomain; } public override bool IsValid(object value) {
string[] splitedEmail = value.ToString().Split("@"); foreach(var v in AllowedDomain) { if(v.ToUpper()==splitedEmail[1].ToUpper()) { return true; }
} return false; } } Hope this code is helpful, have a nice chance.
@@abderrahmanrahou9189 Thank you kindly for this idea. I have a tested the following solution. VALIDEMAILDOMAINATTRIBUTE public class ValidEmailDomainAttribute : ValidationAttribute { private readonly string[] allowedDomain; public ValidEmailDomainAttribute(string[] allowedDomain) { this.allowedDomain = allowedDomain; } public override bool IsValid(object value) { foreach (var dom in allowedDomain) { string[] emailDomain = value.ToString().Split("@"); string thisEmailDomain = emailDomain[1]; string domElement = dom.ToString().ToUpper(); if (thisEmailDomain.ToString().ToUpper() == domElement.ToUpper()) { return thisEmailDomain == dom; } } return false; } } REGISTERVIEWMODEL public class RegisterViewModel { public string City { get; set; } [Required] [EmailAddress] [Remote(action: "IsEmailInUse", controller: "Account")] [ValidEmailDomain(allowedDomain: new string[] { "abc.com", "xyz.com" }, ErrorMessage = "Email domain must be abc.com or xyz.com.")] public string Email { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name ="Confirm Password")] [Compare("Password", ErrorMessage ="Password and confirmation do not match.")] public string ConfirmPassword { get; set; } } }
This is how you do client side validations for custom attribute. stackoverflow.com/questions/41900485/custom-validation-attributes-comparing-two-properties-in-the-same-model
What if the domain name you want to validate with is pragimtech.com and user enters Pragimtech.com. The validation will fail but it is not advisable to make it case sensitive comparison thats the reason.
a whole academy in one person, thank you so much CREATIVE GUY
You are a gifted teacher! I understand everything you say, you are very articulate on explaining them without making me feel like I'm stupid. I have this issue to create custom validation on one special field called cost centre based on SAP validation. I'm going to try this next Monday. Wished me luck!
You are the great lecturer I ever met. all the best
Sir, how can we have client side validations for custom attr
Do you got the answer??
This worked to me.
//Validation attribute
public class ValidEmailDomainAttribute :ValidationAttribute, IClientModelValidator
{
public string AllowedDomain { get; }
public ValidEmailDomainAttribute(string AllowedDomain)
{
this.AllowedDomain = AllowedDomain;
}
public override bool IsValid(object value)
{
return (value as string).EndsWith(AllowedDomain);
}
public void AddValidation(ClientModelValidationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-ValidEmailDomain","Error: "+ ErrorMessage);
context.Attributes.Add("data-val-AllowedDomain", AllowedDomain);
}
}
//javascript in the view
(function ($) {
$.validator.addMethod('data-val-ValidEmailDomain',
function (value, element, params) {
debugger;
value.slice()
var domain = $(element).attr('data-val-AllowedDomain');
if (domain) {
return value.slice(-1 * domain.length) === domain;
}
return false;
}, function (params, element) {
debugger;
var msgCompare = $(element).attr('data-val-ValidEmailDomain');
if (!msgCompare) {
msgCompare = 'Domain of email is not allowed.';
}
return msgCompare;
});
$.validator.unobtrusive.adapters.addBool('data-val-ValidEmailDomain');
})(jQuery);
There is another example in the below link[1], I used it as reference ( but the article is in portuguese).
[1] medium.com/@fulviocanducci/aspnet-core-valida%C3%A7%C3%A3o-customizadas-server-side-e-client-side-55a7972757d4
Good question. Maybe we have to write the validation logic as a "Remote" action instead of a custom validation attribute?
@@gabrielbarreto5377 Thanks, worked.
Hi Venkat how to make a custom validation attribute to work on client side.
I affraid that anyone type only "test@" and click register your code crash :) But it's a detail. Great video, like always!
Thank you for the pointer, I missed this one too, yes index 1 would be null and an exception would be raised....but I noticed that I have EmailAddress DataAttribute on Email Property so test@ would be an invalid email address that the client-side validation would pickup and block posting it.
@@admiremhlaba1192 Kud Venkat is a woman? 🤔
@@maikeru_pk I don't believe you but thanks for the heads up
@@admiremhlaba1192 No no it's just a joke :) Sorry, God bless you Admire :)
@@maikeru_pk Be Blessed More My Human Friend - I don't know your gender so I'm using Generics
You're amazing!
Super venkat and one more thing i don't know why all people skip custom client side validation for Core version. Please consider
why do you use the ErrorMessage prop from the base class, isn't there a way to set it through the base() ctor?
Nice explanation sir
Hey, thank you once again for your detailed explanation. I guess you cannot do something similar to this if you are using a shared class library, can you? My models are stored in the class library adjacent to my web project. I have a reference from my web project to the class library but it will not allow me to use the custom attribute from the class library back to the web project. It's working to an extent as long as the custom validator is coming from the class library but since the custom validator is not in the web project, it's not showing the validation in red when I hit submit. But it's partially working as long as I have a "." in my input field which is what I did for validating only a domain name like "my.domain". I have to enter a "." in the input field or else it fails, I just wish the red validation would cooperate :/ Thanks.
This video concludes saying it works "just like any other validation attribute" that is not true. There is no client side validation, so the form must post before the attribute runs. That is problematic if the user has filled out form fields that depend on dynamic controls because they will lost their data.
Sir, When i am defining [ValidEmailDomain] attribute in RegisterViewModel class and press [ctrl .] then it is not recognising EmployeeManagement.Utilities namespace ?
for sure you have misspelling or typo error. Check and make sure you type class name correctly.
If I have an integer type attribute but the value entered by the user is greater than the maximum value allowed for integers, how do I validate it and display a custom message?
How can you trigger the custom validation attribute on lost focus? I want my custom validation to work exactly like the EmailAddress or Required attribute
Thank you sir.
What about custom validations for client and remote?
thank you
Thanks for great explanation, Please create a video on client side custom validation as well.
Hello Manish - Client side validation is covered in details in Parts 74 to 76. Here is the link to complete ASP.NET Core MVC tutorial.
www.pragimtech.com/courses/asp-net-core-mvc-tutorial-for-beginners/
@@Csharp-video-tutorialsBlogspot No venkat, this custom attribute only working on server side only and we should write for client side also.
@@vinothdharmaraj7510 Taking into consideration that maybe you want 2 remote validations for the same field that is email, .net core doesnt let you add multiple remote attributes so, you could create a method IsEmailValid and check within if the email is in use or if the email match with domain "PREGIM.COM" like Lin mentioned here stackoverflow.com/questions/20329121/multiple-remote-validation-attribute-in-asp-net-mvc4.
Hope it helps you Vinoth, Venkat I admire you everyday, thanks for giving us free education for future engineers or good programmers, regards..
Hi, Anyone can you help. For Some reason the IsValid Method doesnt fire for me. I have no Compile time errors. Any ideas?
Sir even my IsValid overridden function is not getting executed, did you found the reason? Please share.
@@kunalshah7270 what is happening can you elaborate
Did you get any solution to this? I haven't try it yet but I have high hope for it to works 😅 seeing this message making the hope seems a bit dimmer
great
Kudvenkat Sir, I have done exact replications of the steps that you have shown in video still my IsValid function is getting called only on click of Submit nor I have any compile time errors, what might be the reason? Can you please help?
Did you find the solution? I am also having the same issue
@@lifetraveler8008 No sir not yet.
wouldnt that be much easier to just call value.EndsWith(allowedDomain)?
and safer
Don't think so. ex: allowed domain is "mail.com".....I can add "gmail.com". It is better to split the string with '@'.
how can you implement custom attribute on client side ????
How can I allowed more than one domain?
Hi, to allow more than one domain you should pass an Array of string, and this is code source:
for RegisterViewModel class:
[RegisterEmailDomainValidation(AllowedDomain: new string[] {"gmail.com","hotmail.com"}
,ErrorMessage ="This email domain should be: gmail.com or hotmail.com")]
public string Email { get; set; }
---------------------------------------------------------------------------------------------------------------------------------------------------------
For ValideEmailAttribute class:
public class ValideEmailAttribute : ValidationAttribute
{
private readonly string[] AllowedDomain;
public ValideEmailAttribute (string[] AllowedDomain)
{
this.AllowedDomain = AllowedDomain;
}
public override bool IsValid(object value)
{
string[] splitedEmail = value.ToString().Split("@");
foreach(var v in AllowedDomain)
{
if(v.ToUpper()==splitedEmail[1].ToUpper())
{
return true;
}
}
return false;
}
}
Hope this code is helpful, have a nice chance.
@@abderrahmanrahou9189 Thank you kindly for this idea. I have a tested the following solution.
VALIDEMAILDOMAINATTRIBUTE
public class ValidEmailDomainAttribute : ValidationAttribute
{
private readonly string[] allowedDomain;
public ValidEmailDomainAttribute(string[] allowedDomain)
{
this.allowedDomain = allowedDomain;
}
public override bool IsValid(object value)
{
foreach (var dom in allowedDomain) {
string[] emailDomain = value.ToString().Split("@");
string thisEmailDomain = emailDomain[1];
string domElement = dom.ToString().ToUpper();
if (thisEmailDomain.ToString().ToUpper() == domElement.ToUpper())
{
return thisEmailDomain == dom;
}
}
return false;
}
}
REGISTERVIEWMODEL
public class RegisterViewModel
{
public string City { get; set; }
[Required]
[EmailAddress]
[Remote(action: "IsEmailInUse", controller: "Account")]
[ValidEmailDomain(allowedDomain: new string[] { "abc.com", "xyz.com" },
ErrorMessage = "Email domain must be abc.com or xyz.com.")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name ="Confirm Password")]
[Compare("Password",
ErrorMessage ="Password and confirmation do not match.")]
public string ConfirmPassword { get; set; }
}
}
Hi Venkat, will you be covering Fluid Validation in this series?
This is how you do client side validations for custom attribute.
stackoverflow.com/questions/41900485/custom-validation-attributes-comparing-two-properties-in-the-same-model
Why should we use ToUpper() function?
What if the domain name you want to validate with is pragimtech.com and user enters Pragimtech.com. The validation will fail but it is not advisable to make it case sensitive comparison thats the reason.
@@IamSandeepKmr Thanks bro
Video thumbnail is wrong, but as always great video
Once I found myself unwittingly 10 videos ahead of the next one, so I think this happened before also.
Thank you sir.