2011-07-28 26 views
38

Me gustaría poner un tiempo de fecha constante en un parámetro de atributo, ¿cómo puedo hacer un datetime constante? Está relacionado con un ValidationAttribute del Bloque de aplicación de validación EntLib, pero también se aplica a otros atributos.Constante DateTime en C#

Cuando hago esto:

private DateTime _lowerbound = new DateTime(2011, 1, 1); 
[DateTimeRangeValidator(_lowerbound)] 

voy a conseguir:

An object reference is required for the non-static field, method, or property _lowerbound 

Y al hacer esto

private const DateTime _lowerbound = new DateTime(2011, 1, 1); 
[DateTimeRangeValidator(_lowerbound)] 

que obtendrá:

El tipo 'System.DateTime' no se puede declarar const

¿Alguna idea? Pasando de esta manera no es preferible:

[DateTimeRangeValidator("01-01-2011")] 

Respuesta

19

La solución siempre he leído sobre es o bien ir a la ruta de una cadena, o pasar el día/mes/año como tres parámetros separados, como C# no lo hace actualmente admite un valor literal de DateTime.

Aquí está un ejemplo sencillo que le permitirá pasar en cualquier tres parámetros de tipo int, o una string en el atributo:

public class SomeDateTimeAttribute : Attribute 
{ 
    private DateTime _date; 

    public SomeDateTimeAttribute(int year, int month, int day) 
    { 
     _date = new DateTime(year, month, day); 
    } 

    public SomeDateTimeAttribute(string date) 
    { 
     _date = DateTime.Parse(date); 
    } 

    public DateTime Date 
    { 
     get { return _date; } 
    } 

    public bool IsAfterToday() 
    { 
     return this.Date > DateTime.Today; 
    } 
} 
+0

¿Es este un constructor? Aún no lo entiendo ¿Puedes proporcionar más código? –

+0

Sí, lo siento, lo he actualizado para incluir un ejemplo para aclarar. –

+0

¡Se ve bien! Comprenlo y lo intentaré. Gracias. –

3

El DateTimeRangeValidator puede tener una representación de cadena (formato ISO8601) como un parámetro

por ejemplo

      LowerBound    UpperBound 
[DateTimeRangeValidator("2010-01-01T00:00:00", "2010-01-20T00:00:00")] 

un parámetro solo obtendrá interpretado como un UpperBound, por lo que necesita 2 si desea ingresar a LowerBound. Verifique los documentos para ver si existe un valor especial 'no me importa' para UpperBound o si necesita establecerlo en una fecha futura muy lejana.

¡Vaya, sólo re-leer y notaron

'Going esta manera no es preferible'

[DateTimeRangeValidator("01-01-2011")] 

Por qué no?

¿Sería

private const string LowerBound = "2010-01-01T00:00:00"; 
private const string UpperBound = "2010-01-20T00:00:00"; 

[DateTimeRangeValidator(LowerBound, UpperBound)] 

ser peor/diferente de (fecha VB formato literal)

private const DateTime LowerBound = #01/01/2000 00:00 AM#; 
private const DateTime UpperBound = #20/01/2000 11:59 PM#; 

[DateTimeRangeValidator(LowerBound, UpperBound)] 

HTH,
Alan

+0

Sé que puedo ir por este camino, pero como dije no es preferible ... y me preguntaba si podría hacerlo un poco más sólido. –

+0

La ventaja de que el literal de fecha VB sobre el uso de un literal de cadena para las fechas es que un problema w/el literal de fecha VB dará como resultado un error en tiempo de compilación, mientras que un problema con el literal de cadena dará como resultado un error de tiempo de ejecución . Eso, y también evita una operación de unboxing. –

+0

Acepte el tiempo de compilación frente al tiempo de ejecución. – AlanT

28

Como algunas de las respuestas anteriores en cuenta, una const DateTime no se admite nativamente en C# y no se puede usar como parámetro de atributo.Sin embargo, un readonly DateTime (que se recomienda sobre const en efectivo de C#, 2ª edición [Artículo 2]) es una solución simple para otras situaciones de la siguiente manera:

public class MyClass 
{ 
    public static readonly DateTime DefaultDate = new DateTime(1900,1,1); 
} 
+12

aunque este miembro de solo lectura estático todavía no se puede usar en parámetros de atributos – tenpn

0

Una solución consiste en dividir la fecha en los campos de día, mes y año, luego extienda RangeAttribute De esta manera obtiene todos los beneficios de la validación integrada.

Consulte el siguiente ejemplo:

public class PermittedYearRangeAttribute : RangeAttribute 
{ 
    public PermittedYearRangeAttribute() 
     : base(1900, DateTime.Now.AddYears(-50).Year) 
    { 
     ErrorMessage = string.Format("Year must be between 1900 and {0}", DateTime.Now.AddYears(-50).Year); 
    } 
} 

En Global.asax.csApplication_Start() método añadir siguiente línea

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(PermittedYearRangeAttribute), typeof(RangeAttributeAdapter)); 

En Características del modelo Decorar:

[Required(ErrorMessage = "Please enter year")] 
    [PermittedYearRange] 
    public int Year { get; set; } 

    [Required(ErrorMessage = "Please enter day")] 
    [Range(1, 31, ErrorMessage = "Day must be between 1 and 31")] 
    public int Day { get; set; } 

    [Required(ErrorMessage = "Please enter month")] 
    [Range(1, 31, ErrorMessage = "Month must be between 1 and 12")] 
    public int Month { get; set; } 

HTML representado:

<input class="tooltip form-control input dob--input input-validation-error" data-val="true" data-val-number="The field Year must be a number." data-val-range="Year must be between 1900 and 1965" data-val-range-max="1965" data-val-range-min="1900" data-val-required="Please enter year" id="Year" maxlength="4096" name="Year" placeholder="YYYY" tabindex="" type="text" value="0">