Reputation: 3647
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
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