proyecto net mvc modelo introducción formularios español desarrollo crear con asp aplicacion c# asp.net-mvc asp.net-mvc-5 model-validation

c# - mvc - introducción a asp net core



Validación del modelo MVC para fecha (4)

Creo que solo agregando el atributo "Rango" funcionará

[Range(typeof(DateTime), "01/01/1900", "06/06/2079", ErrorMessageResourceType = typeof(Resources.Patient), ErrorMessageResourceName = "DateOfBirth_Range")]

¿Hay alguna validación predeterminada para MVC 5 donde puedo establecer el valor mínimo y máximo de la fecha?

En mi modelo quiero validación de fecha.

public class MyClass { [Required(ErrorMessage="Start date and time cannot be empty")] //validate:Must be greater than current date [DataType(DataType.DateTime)] public DateTime StartDateTime { get; set; } [Required(ErrorMessage="End date and time cannot be empty")] //validate:must be greater than StartDate [DataType(DataType.DateTime)] public DateTime EndDateTime { get; set; } }

Ps: De acuerdo con este sitio web de Asp.Net , hay un problema al usar el validador de Range para DateTime, y no se recomienda.

Nota: la validación de jQuery no funciona con el atributo Rango y DateTime. Por ejemplo, el siguiente código siempre mostrará un error de validación del lado del cliente, incluso cuando la fecha esté en el rango especificado:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

Deberá deshabilitar la validación de fecha de jQuery para usar el atributo Rango con DateTime. En general, no es una buena práctica compilar fechas duras en sus modelos, por lo que no se recomienda el uso del atributo Rango y DateTime.

También, sé que hay paquetes de Nuget como Fluent Validation y Foolproof que hacen el truco para validar y verificar si una fecha es mayor que otra, pero quería saber si de manera predeterminada hay algo para verificar el valor mínimo y máximo de la fecha.

Por lo que vi en Novedades de MVC 5.1 , hay soporte para la MaxLength de MaxLength y MinLength .


Lo haría con la interfaz IValidatableObject de System.ComponentModel.DataAnnotations, que le permite agregar reglas de validación adicionales donde puede hacer muchas más comprobaciones. Agregue la interfaz a su clase y luego implemente el método Validate , donde puede comparar StartDateTime con la fecha / hora actual, y también comparar EndDateTime con StartDateTime, por ejemplo

public class MyClass : IValidatableObject { [Required(ErrorMessage="Start date and time cannot be empty")] //validate:Must be greater than current date [DataType(DataType.DateTime)] public DateTime StartDateTime { get; set; } [Required(ErrorMessage="End date and time cannot be empty")] //validate:must be greater than StartDate [DataType(DataType.DateTime)] public DateTime EndDateTime { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { List<ValidationResult> results = new List<ValidationResult>(); if (StartDateTime < DateTime.Now) { results.Add(new ValidationResult("Start date and time must be greater than current time", new []{"StartDateTime"})); } if (EndDateTime <= StartDateTime) { results.Add(new ValidationResult("EndDateTime must be greater that StartDateTime", new [] {"EndDateTime"})); } return results; } }

El único inconveniente potencial de esto es que Validate ejecuta en el lado del servidor, no en la validación de jQuery.


No es necesario deshabilitar la validación de fecha de jQuery (y es probable que cause otros problemas). Solo necesita reemplazar el método de range del $.validator .

De forma predeterminada, funciona con valores numéricos (y luego recurre a una comparación de cadenas), por lo que puede agregar el siguiente script (después de jquery.validate.js y jquery.validate.unobtrusive.js , pero no jquery.validate.unobtrusive.js en $(document).ready

$.validator.methods.range = function(value, element, param) { if ($(element).attr(''data-val-date'')) { var min = $(element).attr(''data-val-range-min''); var max = $(element).attr(''data-val-range-max''); var date = new Date(value).getTime(); var minDate = new Date(min).getTime(); var maxDate = new Date(max).getTime(); return this.optional(element) || (date >= minDate && date <= maxDate); } // use the default method return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); };

Entonces puede usar el RangeAttribute en su propiedad

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")] public DateTime Date { get; set; }


Normalmente uso esta solución cuando quiero validar algo en el servidor. Sé que puede confiar en el Modelo de Validación que usa MVC, pero cuando hago las validaciones, estoy tratando de usar un proyecto separado en caso de que necesite hacer una prueba de unidad para ellos. Digamos que tiene dos aplicaciones, una de Escritorio y una de Web, entonces ambas pueden compartir el Proyecto de Validación en lugar de repetir el código en ambas aplicaciones para la misma "Vista" / "Pantalla". La idea aquí es aislar el Proyecto de Validación como un proyecto independiente de su solución.

Para poder descargar el proyecto FluentValidation de NuGet, FluentValidation usa las reglas dentro del constructor, puede ver la documentación aquí https://github.com/JeremySkinner/FluentValidation/wiki

Su regla de fecha se puede usar solo de esta manera, por ejemplo, allí puede poner reglas para su valor mínimo y su valor máximo también:

public class CustomerValidator: AbstractValidator<Customer> { public CustomerValidator() { RuleFor(customer => customer.startDate) .NotNull() .WithMessage("You should select a start date") .Must(d => d.HasValue && d.Value <= DateTime.Today) .WithMessage("The start date should not be greather than current month/year"); }

Ahora dentro de tu control

[HttpPost] public ActionResult Index(Customer c) { if(ModelState.IsValid) { var validator= new CustomerValidator(); var valResult = validator.Validate(c); if (valResult.Errors.Count != 0) { valResult.Errors.ForEach(x => ModelState.AddModelError(x.PropertyName, x.ErrorMessage)); return View(vm); } //Your code here } }