Skip to content

Instantly share code, notes, and snippets.

@Muscipular
Created April 4, 2019 06:59
Show Gist options
  • Save Muscipular/6c966d3841ddbe062434feb07d4be30a to your computer and use it in GitHub Desktop.
Save Muscipular/6c966d3841ddbe062434feb07d4be30a to your computer and use it in GitHub Desktop.
public class RequireIfAttribute : ValidationAttribute
{
public RequireIfMode Mode { get; }
public Type TargetType { get; }
public string Target { get; }
public bool TargetEmptyAsExists { get; set; }
private Func<object, object> _Accessor;
public RequireIfAttribute(RequireIfMode mode, Type targetType, string target)
{
Mode = mode;
TargetType = targetType;
Target = target;
_Accessor = MemberAccessor(targetType, target);
}
public static Func<object, object> MemberAccessor(Type type, string member)
{
var p = Expression.Variable(typeof(object));
var convert = Expression.Convert(Expression.PropertyOrField(Expression.Convert(p, type), member), typeof(object));
return Expression.Lambda<Func<object, object>>(convert, p).Compile();
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (validationContext.ObjectInstance == null)
{
return ValidationResult.Success;
}
var o = _Accessor(validationContext.ObjectInstance);
var check = false;
switch (Mode)
{
case RequireIfMode.IfExists:
check = o != null && (TargetEmptyAsExists || o is string && !string.IsNullOrWhiteSpace(o as string));
break;
case RequireIfMode.IfNotExists:
check = o == null || (!TargetEmptyAsExists && (o is string && string.IsNullOrWhiteSpace(o as string)));
break;
default:
throw new ArgumentOutOfRangeException();
}
if (check)
{
if (value == null)
{
return new ValidationResult($"{validationContext.DisplayName}不能为空");
}
if (value is string s && s.IsNullOrWhiteSpace())
{
return new ValidationResult($"{validationContext.DisplayName}不能为空");
}
}
return ValidationResult.Success;
}
public string GetDescription()
{
string s;
switch (Mode)
{
case RequireIfMode.IfExists:
s = "不";
break;
case RequireIfMode.IfNotExists:
s = "";
break;
default:
throw new ArgumentOutOfRangeException();
}
return $"当{Target}{s}为空时必填";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment