En ASP.NET MVC 2, ¿cómo haría para vincular una propiedad de modelo de vista que es un DateTime donde la aplicación debe tener 3 listas desplegables para elegir mes, día, año? He leído la publicación de blog de Scott H. sobre fechas vinculantes hace algún tiempo, y eso parece demasiado complicado para un caso tan simple. Seguramente hay una manera más limpia/mejor para hacerlo?ASP.NET mvc 2: vinculando una fecha de nacimiento con menús desplegables
Cualquiera que sea la solución que uso, me gustaría conservar la validación incorporada usando las cosas de DataAnnotations, y también me gustaría poder especificar un rango de fechas mínimo/máximo usando un atributo de validación.
Mi primer pensamiento fue un simple ligante modelo personalizado de este modo:
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
var model = bindingContext.Model as RsvpViewModel;
var form = controllerContext.HttpContext.Request.Form;
if (model == null)
throw new ArgumentException("bindingContext.Model");
if (propertyDescriptor.Name.Equals("BirthDate"))
{
if (!string.IsNullOrEmpty(form["BirthYear"]) &&
!string.IsNullOrEmpty(form["BirthMonth"]) &&
!string.IsNullOrEmpty(form["BirthDay"]))
{
try
{
var yy = int.Parse(form["BirthYear"]);
var mm = int.Parse(form["BirthMonth"]);
var dd = int.Parse(form["BirthDay"]);
model.BirthDate = new DateTime(yy, mm, dd);
return;
}
catch (Exception)
{
model.BirthDate = DateTime.MinValue;
return;
}
}
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
Luego he intentado crear un DateTimeAttribute hacer la validación, pero se encontró con algunas dificultades para especificar un intervalo de fechas en la declaración de atributo porque el parámetro de atributo los tipos son limitados, y DateTime no es uno de los tipos permitidos.
que acabó creando una interfaz IDateRangeProvider y una implementación específica para las fechas de nacimiento de este modo:
public interface IDateRangeProvider
{
DateTime GetMin();
DateTime GetMax();
}
public class BirthDateRangeProvider : IDateRangeProvider
{
public DateTime GetMin()
{
return DateTime.Now.Date.AddYears(-100);
}
public DateTime GetMax()
{
return DateTime.Now.Date;
}
}
Esto me permitió utilizar una propiedad DateTime en mi modelo de vista y retener la totalidad de la construcción en la bondad ..
[DisplayName("Date of Birth:")]
[Required(ErrorMessage = "Date of birth is required")]
[DateTime(ErrorMessage = "Date of birth is invalid", RangeProvider=typeof(BirthDateRangeProvider))]
public DateTime? BirthDate { get; set; }
Pero realmente, toda la solución huele a sobreingeniería y pensar demasiado en ella. ¿No hay una mejor manera?
Publicación excelente, me he estado preguntando cómo hacer lo mismo, excepto elegir la fecha mediante un selector de fecha, pero luego elegir la hora mediante un menú desplegable durante horas y minutos y luego combinarlo para enlazar a un objeto Datetime – MrBliz