Mech0z
Mech0z

Reputation: 3647

How to allow nothing or a certain value for a property in asp.net mvc3

I have 3 properties for a custom class, its Date, Hour and Minute. These represent fields the user can enter, but they are not required, but if one field is filled in then the other 2 should as well (Not sure that part is possible with pure c#)

I have made this code

    [RegularExpression("[0-9]{2}-[0-9]{2}-[0-9]{4}", ErrorMessage = "Date should be in the following format: dd-mm-yyyy")]
    [MaxLength(10)]
    public string Date { get; set; }

    [CustomRange(0, 24, ErrorMessage = "Hour must be between 00 and 24")]
    public string Hour { get; set; }

    [CustomRange(0, 59, ErrorMessage = "Hour must be between 00 and 59")]
    public string Minute { get; set; }

.

    public class CustomRangeAttribute : ValidationAttribute
{
    public int Min { get; set; }
    public int Max { get; set; }


    public CustomRangeAttribute(int min, int max)
    {
        Min = min;
        Max = max;
    }

    public override bool IsValid(object value)
    {
        var stringValue = Convert.ToString(value, CultureInfo.CurrentCulture);
        int tmp;
        if(int.TryParse(stringValue, out tmp))
        {
            return tmp >= Min && tmp <= Max;
        }
        return false;
    }
}

The date part works fine, that one is optional, but the hour and minute it complains about as if they had [Required], so is that possible to make them optional as well?

I changed so I used regular expressions instead

    [RegularExpression("[0-9]{2}-[0-9]{2}-[0-9]{4}", ErrorMessage = "Date should be in the following format: dd-mm-yyyy")]
    [MaxLength(10)]
    public string Date { get; set; }

    [RegularExpression("[0-1]{1}[0-9]{1}|[2]{1}[0-3]{1}")]
    public string Hour { get; set; }

    [RegularExpression("[0-5]{1}[0-9]{1}")]
    public string Minute { get; set; }

Upvotes: 2

Views: 163

Answers (1)

James Harris
James Harris

Reputation: 1914

To meet your requires of certain fields being required only in some situations, you can implement custom validation logic using IValidateableObject

How do I use IValidatableObject?

Provides a good overview

basically

public MyCustomClass:IValidateableObject
{

 public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)    
 { 
      //your custom "model-wide" business rules here
 }
}

As for the Hour and Minute, is there any reason your using a string instead of a nullable int?

ie

[Range(0,24,ErrorMessage="Hour must be between 00 and 24")]
public int? Hour {get; set;}

Edit: Ok now that you have edited your first post and included your Custom Validation Attribute its obvious why it isn't working

Your current code

 public override bool IsValid(object value)     { 
        var stringValue = Convert.ToString(value, CultureInfo.CurrentCulture); 
        int tmp;
         if(int.TryParse(stringValue, out tmp))
         {
             return tmp >= Min && tmp <= Max;
         } 
        return false; 
    }

Will return false whenever value == null.

Adding a check for a nullorempty value is what you need ie

   public override bool IsValid(object value)     { 
       var stringValue = Convert.ToString(value, CultureInfo.CurrentCulture); 

       if (String.IsNullOrEmpty(stringValue))
       {
            return true;
       }
        int tmp;
         if(int.TryParse(stringValue, out tmp))
         {
             return tmp >= Min && tmp <= Max;
         } 
        return false; 
    }

Upvotes: 3

Related Questions