1

In one of the models I've got something like this:

[Required]
[Display(Name="Date of Birth")]
[Range(typeof(DateTime), DateTime.MinValue.ToString(), DateTime.Today.ToString())]
public DateTime BirthDate { get; set; }

But compiler complains that

Error CS0182 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

Is there a way I can do it by attribute or do I have to implement it as validation?

  • 1
    Attributes are metadata and must be known at compile time so its not possible. You need to use a custom conditional attribute where the values are based on other properties in your model. For example you could use a [foolproof](http://foolproof.codeplex.com/) `[LessThanOrEqualTo("BaseDate")]` where `BaseDate` is a property in your model and is set to `DateTime.Today` –  Feb 25 '17 at 00:00
  • 1
    Or to write your own - refer [The Complete Guide To Validation In ASP.NET MVC 3 - Part 2](http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2) which means your could create a `[LessThanOrEqualToToday]` attribute that does not require an additional property in your model. –  Feb 25 '17 at 00:02
  • Note also that you cannot get client side with a `[Range]` attribute using `DateTime` values unless you modify the `$.validator` as per [this answer](http://stackoverflow.com/questions/21777412/mvc-model-validation-for-date/42036626#42036626) –  Feb 25 '17 at 00:59

2 Answers2

2

Write your own Attribute PastDateAttribute class that inherits from ValidationAttribute. Then annotate the property BirthDate with [PastDate].

A sample implementation is for example here:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class PastDateAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        DateTime? dateValue = value as DateTime?;
        var memberNames = new List<string>() {context.MemberName};

        if (dateValue != null)
        {
            if (dateValue.Value.Date > DateTime.UtcNow.Date)
            {
                return new ValidationResult(Resources.PastDateValidationMessage, memberNames);
            }
        }

        return ValidationResult.Success;
    }
}

Usage:

[Required]
[Display(Name="Date of Birth")]
[PastDate]
public DateTime BirthDate { get; set; }
NineBerry
  • 26,306
  • 3
  • 62
  • 93
0

You must specify const. static string is not const. That attribute wants to const string not static string.

For best practice create a class and add const dateMinValue and dateMaxvalue. Or you can add manually "Monday, January 1, 0001". But i prefer static class and add like const string, its easier.

orhun.begendi
  • 937
  • 3
  • 16
  • 31
  • Thank you for your answer. But I would like to use something not that const - DateTime.Today. So it means I have to write a validator for it? – Farrah Jiang Feb 24 '17 at 22:58