C# 返回多个ValidationException
我一直在尝试将服务器端DataAnnotation验证合并到我的项目中,我发现DataAnnotations有它自己的错误类型,ValidationException。但我的问题是,它一次只返回一个验证错误,因此,如果3个属性验证失败,则只会抛出第一个属性。我正在寻找一种将所有错误作为异常抛出的方法,因此它不会通知用户/开发人员验证失败,而是会一次性声明哪些属性/字段未通过验证 我找到了Validator.TryValidateObject(…)方法,但它只是填充ValidationResults,让开发人员可以选择是否抛出和异常。我当前实现的是迭代ValidationResults以创建一个ValidationException列表,将该列表包装到AggregateException中,然后在其InnerException中抛出另一个ValidationException和AggregateExceptionC# 返回多个ValidationException,c#,validation,error-handling,data-annotations,C#,Validation,Error Handling,Data Annotations,我一直在尝试将服务器端DataAnnotation验证合并到我的项目中,我发现DataAnnotations有它自己的错误类型,ValidationException。但我的问题是,它一次只返回一个验证错误,因此,如果3个属性验证失败,则只会抛出第一个属性。我正在寻找一种将所有错误作为异常抛出的方法,因此它不会通知用户/开发人员验证失败,而是会一次性声明哪些属性/字段未通过验证 我找到了Validator.TryValidateObject(…)方法,但它只是填充ValidationResult
ValidationContext validationContext = new ValidationContext(entity, null, null);
List<ValidationResult> validationResults = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(entity, validationContext, validationResults, true);
if (!isValid)
{
List<ValidationException> validationErrors = new List<ValidationException>();
foreach (ValidationResult validationResult in validationResults)
{
validationErrors.Add(new ValidationException(validationResult.ErrorMessage);
}
throw new ValidationException("Entity validation failed.", new AggregateException(validationErrors));
}
ValidationContext ValidationContext=新的ValidationContext(实体,null,null);
列表验证结果=新列表();
bool isValid=Validator.TryValidateObject(实体,validationContext,validationResults,true);
如果(!isValid)
{
列表验证错误=新建列表();
foreach(ValidationResult ValidationResult in validationResults)
{
添加(新的ValidationException(validationResult.ErrorMessage);
}
抛出新的ValidationException(“实体验证失败”)、新的AggregateException(validationErrors);
}
所以基本上,我的问题是:
关于你的第一个问题,“为什么语言不支持X”的标准答案这只是成本与收益的对比,我相信这也适用于这里。人们并不经常遇到需要抛出多个错误的场景……因此设计和实现C#的人认为C#团队设计和实现“抛出多个异常”所需的时间该功能将更好地用于为更多人提供更多好处的功能
并且考虑语言用户的成本——在你当前的任何地方都有“catch(异常e)”,你必须做“catch(iQualaby Exchange)”,而后面是一个前缀,以防你调用的API抛出多个异常。
ValidationContext validationContext = new ValidationContext(entity, null, null);
List<ValidationResult> validationResults = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(entity, validationContext, validationResults, true);
if (!isValid)
{
List<ValidationException> validationErrors = new List<ValidationException>();
foreach (ValidationResult validationResult in validationResults)
{
validationErrors.Add(new ValidationException(validationResult.ErrorMessage);
}
throw new ValidationException("Entity validation failed.", new AggregateException(validationErrors));
}
关于你的第二个问题,我认为将ValidationException与AggregateException结合起来,并将聚合设置为顶级ValidationException的内部异常,是解决问题的一种相当简单的方法……但这不是标准的,所以希望“捕获”的人异常层次结构的另一面是与您密切沟通的人
您还可以考虑将验证结果集合存储在验证异常的数据属性中。这有点简单。数据属性没有被广泛使用,但它对于像这样的非标准场景是存在的。
很难说这两种方法中哪一种更好,但我倾向于第一种。它更复杂,但我认为,如果你建立在InnerException和AggregateException的基础上,任意编码者发现你所做的事情的可能性会更高。我的意思是,你最后一次在运行时转储Exception.Data的内容是什么时候我们在调试什么东西吗?是的,我也是。:-)关于你的第三个问题,我想我应该根据ValidationResult的内容构建ValidationException的消息。例如,“成员{0}无效:{1}”。回答第一个问题: 因为每个验证属性都有自己的
IsValid
属性,并返回公共验证结果(string errorMessage,IEnumerable MemberName)代码>验证结果,您可以从成员名称列表中获取成员名称。因此,属性返回的每个验证都是有效的。您在实体的属性上应用的实体具有验证不是一个好主意
回答第二个问题:
您可以创建自己的ValidationAttribute
列表来验证实体:
var validationResults = new List<ValidationResult>();
var validationAttributes = new List<ValidationAttribute>();
validationAttributes.Add(new CustomValidationAttribute(typeof(ClaimValidator), "ValidateClaim"));
var result = Validator.TryValidateValue(claimObject,
new ValidationContext(claimObject, null, null),
validationResults,
validationAttributes);
我的情况与您类似,我想您已经实施了一个可扩展的体面解决方案?