validar validación validacion regulares mvc formulario expresiones electronico ejemplos dataannotations correo campos jquery asp.net-mvc asp.net-mvc-3 validation

jquery - validación - validar correo electronico mvc



Validación personalizada de MVC: compare dos fechas (4)

Debe modificar el script del lado del cliente para verificar el prefijo del elemento probado y agregar el prefijo (si corresponde) a su selector, de la siguiente manera:

$.validator.addMethod("isdateafter", function(value, element, params) { var parts = element.name.split("."); var prefix = ""; if (parts.length > 1) prefix = parts[0] + "."; var startdatevalue = $(''input[name="'' + prefix + params.propertytested + ''"]'').val(); if (!value || !startdatevalue) return true; return (params.allowequaldates) ? Date.parse(startdatevalue) <= Date.parse(value) : Date.parse(startdatevalue) < Date.parse(value); });

Creé un ValidationAttribute personalizado que compara 2 fechas y se asegura de que la segunda fecha sea mayor que la primera:

public sealed class IsDateAfter : ValidationAttribute, IClientValidatable { private readonly string testedPropertyName; private readonly bool allowEqualDates; public IsDateAfter(string testedPropertyName, bool allowEqualDates = false) { this.testedPropertyName = testedPropertyName; this.allowEqualDates = allowEqualDates; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName); if (propertyTestedInfo == null) { return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName)); } var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); if (value == null || !(value is DateTime)) { return ValidationResult.Success; } if (propertyTestedValue == null || !(propertyTestedValue is DateTime)) { return ValidationResult.Success; } // Compare values if ((DateTime)value >= (DateTime)propertyTestedValue) { if (this.allowEqualDates) { return ValidationResult.Success; } if ((DateTime)value > (DateTime)propertyTestedValue) { return ValidationResult.Success; } } return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientValidationRule { ErrorMessage = this.ErrorMessageString, ValidationType = "isdateafter" }; rule.ValidationParameters["propertytested"] = this.testedPropertyName; rule.ValidationParameters["allowequaldates"] = this.allowEqualDates; yield return rule; }

Clase CalendarEntry: ...

public virtual DateTime StartDate { get; set; } [IsDateAfter("StartDate", true, ErrorMessage="End date needs to be after start date")] public virtual DateTime EndDate { get; set; }

VER:

$.validator.unobtrusive.adapters.add( ''isdateafter'', [''propertytested'', ''allowequaldates''], function (options) { options.rules[''isdateafter''] = options.params; options.messages[''isdateafter''] = options.message; }); $.validator.addMethod("isdateafter", function(value, element, params) { alert(params.propertytested); var startdatevalue = $(''input[name="'' + params.propertytested + ''"]'').val(); if (!value || !startdatevalue) return true; return (params.allowequaldates) ? Date.parse(startdatevalue) <= Date.parse(value) : Date.parse(startdatevalue) < Date.parse(value); }, '''');

Esto funciona bien cuando CalendarEntry no está dentro de otra clase. SIN EMBARGO, cuando uso un modelo de vista así:

public class TrainingDateEditViewModel { #region Properties /// <summary> /// Gets or sets CalendarEntry. /// </summary> public CalendarEntry CalendarEntry { get; set; } ....

La validación del cliente ya no funciona porque la salida html producida es la siguiente:

<input type="text" value="" name="CalendarEntry.EndDate" id="CalendarEntry_EndDate" data-val-isdateafter-propertytested="StartDate" data-val-isdateafter-allowequaldates="True" data-val-isdateafter="End date needs to be after start date" data-val="true">

Y el

data-val-isdateafter-propertytested="StartDate" and IT SHOULD BE: "CalendarEntry.StartDate".

¿Cómo podría hacerlo para que se uniera a la regla "CalendarEntry.StartDate". ValidationParameters ["propertytested"] = this.testedPropertyName; // AQUÍ DEBE SER EL NOMBRE COMPLETO ??? ¿¿CÓMO??

Gracias


En la última respuesta, faltaron algunos paréntesis en la llamada a toLowerCase, aquí hay una versión actualizada con el documento listo y la parte $ .validator.unobtrusive ...-:

$(function () { $.validator.addMethod("isdateafter", function(value, element, params) { var parts = element.name.split("."); var prefix = ""; for (var i = 0; i < parts.length - 1; i++) { prefix = parts[i] + "."; } var startdatevalue = $(''input[name="'' + prefix + params.propertytested + ''"]'').val(); if (!value || !startdatevalue) return true; var allowequal = params.allowequaldates.toLowerCase() === "true"; return allowequal ? Date.parse(startdatevalue) <= Date.parse(value) : Date.parse(startdatevalue) < Date.parse(value); }); $.validator.unobtrusive.adapters.add(''isdateafter'', [''propertytested'', ''allowequaldates''], function (options) { options.rules[''isdateafter''] = options.params; options.messages[''isdateafter''] = options.message; }); });


No olvide incluir el lado del cliente dentro de este código. ¡Me llevó horas encontrar que esto faltaba!

(function ($) { // your code here.. })(jQuery);


Solo para corregir un pequeño error en el javascript de counsellorben: el "(params.allowequaldates)" se interpretará como una cadena (que tendrá un valor de "False" o "True"), pero esa cadena siempre se evaluará como verdadera, permitiendo siempre las mismas fechas. Si también desea permitir más niveles de anidación de sus objetos que solo 1, obtendrá:

$.validator.addMethod("isdateafter", function(value, element, params) { var parts = element.name.split("."); var prefix = ""; for (var i = 0; i < parts.length - 1; i++) prefix = parts[i] + "."; var startdatevalue = $(''input[name="'' + prefix + params.propertytested + ''"]'').val(); if (!value || !startdatevalue) return true; var allowequal = params.allowequaldates.toLowerCase === "true"; return allowequal ? Date.parse(startdatevalue) <= Date.parse(value) : Date.parse(startdatevalue) < Date.parse(value); });