C# 如何在ASP.NET中干净地共享数据模型、视图模型和DTO的自定义验证器(ValidationAttribute)
我正在学习ASP.NETMVC课程。我正在使用ASP.NETWebAPI 2构建RESTWebAPI。该应用程序还包含标准MVC5视图。我使用DTO(数据传输对象)将API与数据模型解耦。我已经创建了一个自定义ValidationAttribute,并将其应用于数据模型中的属性,我希望对DTO上的属性以及MVC视图中使用的属性ViewModel使用相同的验证属性 这需要将C# 如何在ASP.NET中干净地共享数据模型、视图模型和DTO的自定义验证器(ValidationAttribute),c#,asp.net,asp.net-mvc,model-binding,validationattribute,C#,Asp.net,Asp.net Mvc,Model Binding,Validationattribute,我正在学习ASP.NETMVC课程。我正在使用ASP.NETWebAPI 2构建RESTWebAPI。该应用程序还包含标准MVC5视图。我使用DTO(数据传输对象)将API与数据模型解耦。我已经创建了一个自定义ValidationAttribute,并将其应用于数据模型中的属性,我希望对DTO上的属性以及MVC视图中使用的属性ViewModel使用相同的验证属性 这需要将ValidationContext.ObjectInstance强制转换为正确的类型。我已经找到了一个简单的解决方案,但我觉得
ValidationContext.ObjectInstance
强制转换为正确的类型。我已经找到了一个简单的解决方案,但我觉得它不是很优雅,我想知道是否有更好的方法来做到这一点
我所说的特定ValidationAttribute和属性:
[Min18YearsIfAMember]
public DateTime? DateOfBirth { get; set; }
在解决方案的上下文中(为了简洁起见删除了一些详细信息,包括CustomServiceWModel):
它是可读的,但我发现它很难看,必须检查每个可能的情况,比如像客户那样检查ValidationContext.ObjectInstance
有更好的方法吗?在数据注释属性中,可以在附加属性时指定从属属性,并使用该属性验证对象类型的属性:
public class Min18YearsIfAMemberAttribute : ValidationAttribute
{
private string _dependentProperty { get; set; }
public Min18YearsIfAMemberAttribute(string dependentProperty)
{
this._dependentProperty = dependentProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var field = validationContext.ObjectType.GetProperty(_dependentProperty);
if (field != null)
{
var dependentValue = (byte)field.GetValue(validationContext.ObjectInstance, null);
return DoValidation(dependentValue, (DateTime?)value);
}
else
{
return new ValidationResult("<Your message here>");
}
}
private ValidationResult DoValidation( int membershipTypeId, DateTime? DateOfBirth)
{
// Do the validation....
}
太好了!我喜欢这个解决方案允许我们使用具有不同名称的依赖属性的方式。但是,我知道我没有说明性能是一项要求,如果我错了,请纠正我,但是我认为调用
validationContext.ObjectType.GetProperty
可能比使用as
操作符尝试执行类型转换要慢。您可以根据validationContext.ObjectType.GetProperty的类型在静态字典中捕获validationContext.ObjectInstance
的输出。但是,field.GetValue
也用于通过无法缓存的反射检索值。。。您可以运行基准测试来确定它是否真的值得关注,我是否遗漏了什么?您有var dependentValue=(byte).
然后检查dependentValue
是否为空-但它不能为空,因为它是一种值类型。@Wailae您是对的。我已经提出了一些修改建议,但尚未获得批准。@WaiHaLee-是的,我错了,我已经更新了代码
public class Min18YearsIfAMemberAttribute : ValidationAttribute
{
private string _dependentProperty { get; set; }
public Min18YearsIfAMemberAttribute(string dependentProperty)
{
this._dependentProperty = dependentProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var field = validationContext.ObjectType.GetProperty(_dependentProperty);
if (field != null)
{
var dependentValue = (byte)field.GetValue(validationContext.ObjectInstance, null);
return DoValidation(dependentValue, (DateTime?)value);
}
else
{
return new ValidationResult("<Your message here>");
}
}
private ValidationResult DoValidation( int membershipTypeId, DateTime? DateOfBirth)
{
// Do the validation....
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public MembershipType MembershipType { get; set; }
public byte MembershipTypeId { get; set; }
[Min18YearsIfAMember(nameof(MembershipTypeId))]
public DateTime? DateOfBirth { get; set; }
}