控制台环境中的C#自定义属性验证
我的问题是关于在C#中使用自定义属性进行验证 我不太明白验证是如何工作的。我已经声明了一个属性,其中包含验证规则,但是当应该抛出错误时,它不会抛出 属性:控制台环境中的C#自定义属性验证,c#,validation,attributes,C#,Validation,Attributes,我的问题是关于在C#中使用自定义属性进行验证 我不太明白验证是如何工作的。我已经声明了一个属性,其中包含验证规则,但是当应该抛出错误时,它不会抛出 属性: [AttributeUsage(AttributeTargets.Property)] public class NotNullAttribute : Attribute { public bool IsValid(object value) { if (value is string && (
[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
public bool IsValid(object value)
{
if (value is string && (string)value != "")
{
return false;
}
return true;
}
}
在属性内部,我检查属性是否为string类型,其值是否为空字符串,因为这是我必须检查的
任务是检查属性是否为字符串
,如果为空字符串,则该属性无效,否则为空字符串
我的人
班级:
class Person
{
[NotNull]
public string Name { get; set; }
}
这里我应用了自定义属性
主要方法:
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "";
Console.WriteLine("Validation done");
Console.ReadKey();
}
}
在这里,我实例化了Person
类,并为Name
属性分配了一个空字符串。我想这就是应该抛出错误的地方
所以我的问题是为什么不进行验证?我应该从属性调用IsValid
方法吗
我会对此做一些解释,提前谢谢你 属性本身只是属性的“装饰器”。如果没有调用它,它将不会自动执行或使用 但是,在您的情况下,当您可以使用属性本身时,我不认为使用属性有什么意义:
private string _name = "";
public string Name
{
get
{
return _name;
}
set
{
if ( string.IsNullOrEmpty(value) )
{
//throw or fallback
}
else
{
_name = value;
}
}
}
执行基本值验证正是作业属性设置器的优势所在。如果有人使用了无效值,您可以抛出异常,或者设置回退值
如果仍然希望使用属性,则仍然需要一些代码来执行验证本身。而且,任何人都可以为属性指定任何有效值,除非执行了验证
例如,在模型绑定期间使用属性验证—它检查绑定模型类上的验证属性,并在action方法开始执行之前进行验证
属性验证示例
下面是一个简单的示例,说明如何使代码与反射一起工作
首先,这里是验证属性的稍微更新版本:
[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
public bool IsValid(object value)
{
if (!string.IsNullOrEmpty(value as string))
{
return false;
}
return true;
}
}
您的代码实际上只允许一个null
或“
值,我想这与您想要的正好相反。此版本仅在字符串不为空且不为空时有效
现在在程序
类中创建一个验证
方法:
private static bool Validate(object model)
{
foreach (var propertyInfo in model.GetType().GetProperties())
{
foreach (var attribute in propertyInfo.GetCustomAttributes(true))
{
var notNullAttribute = attribute as NotNullAttribute;
if (notNullAttribute != null)
{
if (!notNullAttribute.IsValid(propertyInfo.GetValue(model)))
{
return false;
}
}
}
}
return true;
}
这基本上收集传入参数类型的所有属性,检查NotNullAttribute
属性的所有属性,然后根据模型的当前值执行属性的IsValid
方法
最后,这里是如何从Main
调用它:
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "d";
if (Validate(p1))
{
Console.WriteLine("Valid");
}
else
{
Console.WriteLine("Invalid");
}
Console.WriteLine("Validation done");
Console.ReadKey();
}
现在,如果您计划添加更多验证属性,我将首先创建一个接口:
public interface IValidationAttribute
{
bool IsValid(object value);
}
然后从IValidationAttribute
派生所有验证属性,并在Validate
方法中使用IValidationAttribute
代替NotNullAttribute
。通过这种方式,代码变得更加经得起未来的考验,因为您可以根据接口编程并随时添加新的验证属性。属性本身只是属性的“装饰器”。如果没有调用它,它将不会自动执行或使用
public class BankAccount
{
public enum AccountType
{
Saving,
Current
}
[Required(ErrorMessage="First Name Required")]
[MaxLength(15,ErrorMessage="First Name should not more than 1`5 character")]
[MinLength(3,ErrorMessage="First Name should be more than 3 character")]
public string AccountHolderFirstName { get; set; }
[Required(ErrorMessage="Last Name Required")]
[MaxLength(15,ErrorMessage="Last Name should not more than 1`5 character")]
[MinLength(3,ErrorMessage="Last Name should be more than 3 character")]
public string AccountHolderLastName { get; set; }
[Required]
[RegularExpression("^[0-9]+$", ErrorMessage = "Only Number allowed in AccountNumber")]
public string AccountNumber { get; set; }
public AccountType AcType { get; set; }
[AccountBalaceCheckAttribute]
public double AccountBalance { get; set; }
}
但是,在您的情况下,当您可以使用属性本身时,我不认为使用属性有什么意义:
private string _name = "";
public string Name
{
get
{
return _name;
}
set
{
if ( string.IsNullOrEmpty(value) )
{
//throw or fallback
}
else
{
_name = value;
}
}
}
执行基本值验证正是作业属性设置器的优势所在。如果有人使用了无效值,您可以抛出异常,或者设置回退值
如果仍然希望使用属性,则仍然需要一些代码来执行验证本身。而且,任何人都可以为属性指定任何有效值,除非执行了验证
例如,在模型绑定期间使用属性验证—它检查绑定模型类上的验证属性,并在action方法开始执行之前进行验证
属性验证示例
下面是一个简单的示例,说明如何使代码与反射一起工作
首先,这里是验证属性的稍微更新版本:
[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
public bool IsValid(object value)
{
if (!string.IsNullOrEmpty(value as string))
{
return false;
}
return true;
}
}
您的代码实际上只允许一个null
或“
值,我想这与您想要的正好相反。此版本仅在字符串不为空且不为空时有效
现在在程序
类中创建一个验证
方法:
private static bool Validate(object model)
{
foreach (var propertyInfo in model.GetType().GetProperties())
{
foreach (var attribute in propertyInfo.GetCustomAttributes(true))
{
var notNullAttribute = attribute as NotNullAttribute;
if (notNullAttribute != null)
{
if (!notNullAttribute.IsValid(propertyInfo.GetValue(model)))
{
return false;
}
}
}
}
return true;
}
这基本上收集传入参数类型的所有属性,检查NotNullAttribute
属性的所有属性,然后根据模型的当前值执行属性的IsValid
方法
最后,这里是如何从Main
调用它:
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "d";
if (Validate(p1))
{
Console.WriteLine("Valid");
}
else
{
Console.WriteLine("Invalid");
}
Console.WriteLine("Validation done");
Console.ReadKey();
}
现在,如果您计划添加更多验证属性,我将首先创建一个接口:
public interface IValidationAttribute
{
bool IsValid(object value);
}
然后从IValidationAttribute
派生所有验证属性,并在Validate
方法中使用IValidationAttribute
代替NotNullAttribute
。通过这种方式,代码变得更加经得起未来的考验,因为您可以随时针对接口编程并添加新的验证属性
public class BankAccount
{
public enum AccountType
{
Saving,
Current
}
[Required(ErrorMessage="First Name Required")]
[MaxLength(15,ErrorMessage="First Name should not more than 1`5 character")]
[MinLength(3,ErrorMessage="First Name should be more than 3 character")]
public string AccountHolderFirstName { get; set; }
[Required(ErrorMessage="Last Name Required")]
[MaxLength(15,ErrorMessage="Last Name should not more than 1`5 character")]
[MinLength(3,ErrorMessage="Last Name should be more than 3 character")]
public string AccountHolderLastName { get; set; }
[Required]
[RegularExpression("^[0-9]+$", ErrorMessage = "Only Number allowed in AccountNumber")]
public string AccountNumber { get; set; }
public AccountType AcType { get; set; }
[AccountBalaceCheckAttribute]
public double AccountBalance { get; set; }
}
如何验证
public class GenericValidator
{
public static bool TryValidate(object obj, out ICollection<ValidationResult> results)
{
var context = new ValidationContext(obj, serviceProvider: null, items: null);
results = new List<ValidationResult>();
return Validator.TryValidateObject(
obj, context, results,
validateAllProperties: true
);
}
}
公共类GenericValidator
{
公共静态bool TryValidate(对象对象对象,输出ICollection结果)
{
var context=newvalidationcontext(obj,serviceProvider:null,items:null);
结果=新列表();
返回验证程序.TryValidateObject(
目标、背景、结果、,
validateAllProperties:true
);
}
}
范例
static void Main(string[] args)
{
var bankAccount = new BankAccount();
ICollection<ValidationResult> lstvalidationResult;
bool valid = GenericValidator.TryValidate(bankAccount, out lstvalidationResult);
if (!valid)
{
foreach (ValidationResult res in lstvalidationResult)
{
Console.WriteLine(res.MemberNames +":"+ res.ErrorMessage);
}
}
Console.ReadLine();
}
static void Main(字符串[]args)
{
var bankAccount=新银行账户();
i收集LST验证结果;
bool valid=genericvalidate.TryValidate(bankAccount,out lstvalidationResult);
如果(!有效)
{
对于