Custom regular ExpressionAttribute missing file data-val-regex-template for client-side validation

I created the following custom RegularExpressionAttribute

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class AlphaNumericAttribute: RegularExpressionAttribute, IClientValidatable { public AlphaNumericAttribute() : base("^[-A-Za-z0-9]+$") { } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), ValidationType = "alphanumeric" }; } } 

The field in the ViewModel is decorated with my AlphaNumeric attribute:

 [AlphaNumeric(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = Resources.DriverLicenseNumber_RegexError_)] public string DriverLicenseNumber { get; set; } 

The field is built in the view:

 @using (Html.BeginForm("Index", "Application", FormMethod.Post, new { id = "applicationDataForm", autocomplete = "off" })) { @Html.LabelFor(m => m.DriverLicenseNumber) @Html.ValidationMessageFor(m => m.DriverLicenseNumber) @Html.TextBoxFor(m => m.DriverLicenseNumber) } 

This should result in the corresponding "data" validation attributes in my html input tag. However, the displayed tag is as follows:

 <input data-val="true" data-val-alphanumeric="Please enter a valid driver license number." id="DriverLicenseNumber" name="DriverLicenseNumber" type="text" value="" maxlength="20" class="valid"> 

There are clearly no data-val-regex and data-val-regex-pattern attributes that are supposed to be visualized.

I built other validators with the same structure and they work correctly, like this SSN check, which handles masked spaces for nested input using jquery masking:

 public class SsnAttribute : RegularExpressionAttribute, IClientValidatable { public SsnAttribute() : base("^([0-9]{3}โ€“[0-9]{2}โ€“[0-9]{4})|([ ]{3}โ€“[ ]{2}โ€“[ ]{4})|([0-9]{9,9})$") { } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), ValidationType = "ssn" }; } 

}

With accompanying application in ViewModel:

 [Ssn(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = Resources.SocialSecurity_RegexError_)] public new string SocialSecurityNumber { get; set; } 

The field is built in the view:

 @using (Html.BeginForm("Index", "Application", FormMethod.Post, new { id = "applicationDataForm", autocomplete = "off" })) { @Html.LabelFor(m => m.SocialSecurityNumber) @Html.ValidationMessageFor(m => m.SocialSecurityNumber) @Html.TextBoxFor(m => m.SocialSecurityNumber) } 

This validation attribute correctly displays the data-val-regex and data-val-regex-pattern attributes:

 <input class="SSNMask valid" data-val="true" data-val-regex="Please enter a valid social security number." data-val-regex-pattern="^([0-9]{3}โ€“[0-9]{2}โ€“[0-9]{4})|([ ]{3}โ€“[ ]{2}โ€“[ ]{4})|([0-9]{9,9})$" id="SocialSecurityNumber" name="SocialSecurityNumber" type="text" value="" maxlength="22"> 



I cannot understand what I am missing with the AlphaNumeric attribute, that it does not display the corresponding html attributes.

+4
source share
2 answers

I believe your problem with AlphaNumericAttribute is that you did not add a JavaScript adapter for your alphanumeric type of validation.

You probably have something like this in your code:

 $.validator.unobtrusive.adapters.add('ssn', function(options) { /*...*/ }); 

The client adapter for SsnAttribute declared above the code. Note that it has the ssn name, which is the same as the ModelClientValidationRule property set in the ValidationType .

To fix the problem with AlphaNumericAttribute , you should return ModelClientValidationRegexRule , since it already has all the necessary settings for your case (i.e. the already existing regex adapter).

 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class AlphaNumericAttribute : RegularExpressionAttribute, IClientValidatable { public AlphaNumericAttribute() : base("^[-A-Za-z0-9]+$") { } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRegexRule(FormatErrorMessage(metadata.GetDisplayName()), Pattern); } } 

But if there should be additional logic on the client side for checking the regular expression, you should write and register your own unobtrusive adapter.

To get a larger image and better understand how custom validation can be implemented in ASP.NET MVC, you can refer to the Brad Wilson blog post Unobtrusive client validation in ASP.NET MVC 3 , see Custom adapters for unusual validators .

+9
source

Here is another approach from How to create your own validation attribute for MVC , which is adapted from this article on ASP.NET MVC Custom Validation :

 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class AlphaNumericAttribute: RegularExpressionAttribute { private const string pattern = "^[-A-Za-z0-9]+$"; public AlphaNumericAttribute() : base(pattern) { // necessary to enable client side validation DataAnnotationsModelValidatorProvider.RegisterAdapter( typeof(AlphaNumericAttribute), typeof(RegularExpressionAttributeAdapter)); } } 

Using RegisterAdapter , you can use the integration that already exists for regular expressions for your own inherited type.

+1
source

Source: https://habr.com/ru/post/1494368/


All Articles