Reputation:
I'm using ASP.NET MVC and I wanna create a custom validation attribute to validate StartTime
and EndTime
which refer from the text inputs.
I have tried:
Model:
public class MyModel
{
public bool GoldTime { get; set; }
[TimeValidation(@"^\d{1,2}:\d{1,2}$", GoldTime, ErrorMessage = "Start time is invalid.")]
public string StartTime { get; set; }
[TimeValidation(@"^\d{1,2}:\d{1,2}$", GoldTime, ErrorMessage = "End time is invalid.")]
public string EndTime { get; set; }
}
Validation attribute:
public class TimeValidationAttribute : ValidationAttribute
{
private readonly string _pattern;
private readonly bool _useGoldTime;
public TimeValidationAttribute(string pattern, bool useGoldTime)
{
_pattern = pattern;
_useGoldTime = useGoldTime;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (_useGoldTime)
{
var regex = new Regex(_pattern);
if (!regex.IsMatch(value.ToString()))
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
}
But I'm getting this error message:
An object reference is required for the non-static field, method, or property 'MyModel.GoldTime'
Then, I've tried again by changing GoldTime
(in the model) to true
, the error message would disappear.
So, my question is: How can I pass the parameter GoldTime
to the attribute constructor? I need to use the GoldTime
as a key to enable validating the value of StartTime
and EndTime
.
Thank you!
Upvotes: 1
Views: 3538
Reputation: 50728
It is complaining about using a model property within the attribute definition. Instead, within your custom attribute, you can use properties on the ValidationContext class to get the underlying model, I think via validationContext.ObjectInstance
.
Obviously, you don't want to hard-code the type of model but you could use reflection:
bool goldTime;
var prop = validationContext.ObjectInstance.GetType().GetProperty("GoldTime");
if (prop != null)
goldTime = (bool)prop.GetValue(validationContext.ObjectInstance, null);
Or, define an interface for the model:
public interface ITimeModel
{
bool GoldTime { get; set; }
}
And look for that:
bool goldTime;
if (validationContext.ObjectInstance is ITimeModel)
goldTime = ((ITimeModel)validationContext.ObjectInstance).GoldTime;
Upvotes: 1