2010-09-07 9 views
9

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?

+0

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

Respuesta

1

crear una cabina 3 DROPDOWNLIST y añadir atributo requerido para la validación ellos.

y utilizar BdateList, BMonthList a pueblan su DROPDOWNLIST

[DisplayName("Date of Birth ")] 
public DateTime? Birthdate { get; set; } 

[Required(ErrorMessage = "Date is required")] 
public int BirthDateDate { get; set; } 
[Required(ErrorMessage = "Month is required")] 
public int BirthDateMonth { get; set; } 
[Required(ErrorMessage = "Year is required")] 
public int BirthDateYear { get; set; } 


public List<System.Web.Mvc.SelectList> BDateList 
{ 
    get 
    { 
     // create List here 

    } 
} 

y en el método de post podría asignar valores seleccionados por el usuario para modelar valores BirthDate

BirthDate.Date. AddDays (BirthDateDate -1) .AddMonths (BirthDateMonth)

0

una idea para que

tienen fecha de nacimiento clase

public class birthDate{ 
public int day{get;set;} 
public int month{get;set;} 
public int year{get;set;} 
} 

ahora en su entidad: configurar su elemento fecha de nacimiento para privado

y añadir los artículos de la fecha de nacimiento en la clase Inmediatamente después de manejar el artículo para cada parte juntos. y procesar este a una fecha :)

0

que puede tener el tipo de encargo para el cumpleaños, que tendrá propiedades como

public class BirthDateModel 
{ 
    [Required(), Range(1, 12)] 
    public Int32 BirthMonth { get; set; } 

    [Required, Range(1, 31)] 
    [DayShouldBeValid("BirthYear", "BirthMonth")] 
    public Int32 BirthDay { get; set; } 

    [Required,Range(1990, 2012)] 
    public virtual Int32 BirthYear { get; set; } 

    public DateTimeOffset GetBirthDate() 
    { 
     DateTimeOffset birthDate; 
     if (DateTimeOffset.TryParse(String.Format("{0}-{1}-{2}", BirthMonth, BirthDay, BirthYear), out birthDate)) 
      return birthDate; 

     // what should be returned here? 
     return DateTime.MinValue; 
    } 

} 

Ahora cree encargo validador aka DayShouldBeValid para comprobar si el mes y el año, el día es válida o no.

No cada parte de una fecha tiene su propio control.

Cuestiones relacionadas