我正在寻找一种方法来从我的自定义验证代码中返回以下信息:
public enum ValidationErrorTypeFlags
{
Error_Input = 1 << 0, // a "field specific" error which is checked both clientside and serverside
Error_Input_ServerSide = 1 << 1, // a "field specific" error which can only be checked serverside
Error_General = 1 << 2 // serverside general error
}
在验证代码(IValidatableObject 或 ValidationAttribute)中,当我检测到错误时,我希望能够将上述错误类型之一与 ValidationResult 相关联。
然后我希望能够遍历 Controller 或 View 中的验证错误并区分这些错误类型。
我目前正在使用 MVC 3(很高兴升级到 4)。
注意:
- ModelState 不保留 ValidationResults AFAIK - 您只能访问 ViewData.ModelState.Values.Items[x].Errors 中的错误 - 这些已转换为 System.Web.Mvc.ModelError
- 似乎 MVC 验证只允许您在验证完成后访问 [key, 'error message'] 类型的验证结果。
我目前使用的hack是在自定义验证码中修饰错误信息:
var field = new[] { validationContext.DisplayName };
return new ValidationResult("+Invalid format - use yyyy-mm-dd", field);
然后在 Controller 中查找以+、-、*开头的错误信息。
最佳答案
从自定义验证代码(不知道如何从内置代码完成),您可以通过创建自定义 ValidationResult
来实现通过继承基类并从您的自定义验证属性返回。
public class CustomValidationResult: ValidationResult
{
// additional properties
}
然后您可以从 Controller 中转换并检查验证结果是否为您的自定义类型并采取相应行动。
更新:
上面的想法行不通,因为 ValidationResult
类在 DataAnnotations 程序集中,它们被转换为 ModelValidationResult
这就是我们在 MVC 中可以访问的所有内容。
似乎将额外的信息从数据注释验证传递到 MVC 看起来不太容易!
我正在查看源代码,发现它是 ValidatableObjectAdapter
转换 IEnumerable<ValidationResult>
进入IEnumerable<ModelValidationResult>
.我看不出扩展这个类有什么好处,但我们可以很容易地创建一个自定义的 ValidatableObjectAdapter
通过实现 ModelValidator
并复制 Validate
代码。
我们必须创建一个自定义 ModelValidationResult
和定制ValidationResult
(正是这个自定义 ValidationResult
我们将从验证中返回)并且在 ConvertResults
中方法,我们可以放置处理附加信息的转换代码。
public class CustomValidatableObjectAdapter : ModelValidator
{
public CustomValidatableObjectAdapter(ModelMetadata metadata, ControllerContext context)
: base(metadata, context)
{
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
object model = Metadata.Model;
if (model == null)
{
return Enumerable.Empty<ModelValidationResult>();
}
IValidatableObject validatable = model as IValidatableObject;
if (validatable == null)
{
throw new Exception("model is of not type validatable");
}
ValidationContext validationContext = new ValidationContext(validatable, null, null);
return ConvertResults(validatable.Validate(validationContext));
}
private IEnumerable<ModelValidationResult> ConvertResults(IEnumerable<ValidationResult> results)
{
foreach (ValidationResult result in results)
{
// iterate the ValidationResult enumeration and cast each into CustomValidationResult
// and conver them into enumeration of CustomModelValidationResult.
}
}
}
最后我们要告诉DataAnnotationsModelValidatorProvider
使用我们的 CustomValidatableObjectAdapter
在Application_Start
Global.asax.cs 的事件。
DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory((metadata, context) => new CustomValidatableObjectAdapter(metadata, context));
所以你必须创建一个自定义的ValidationResult
, 定制 ModelValidationResult
和自定义 ValidatableObjectAdapter
.
我还没有测试过这个,但我希望它能起作用。我可能会建议一个比这更好、更简单的解决方案。
关于asp.net-mvc - 如何从自定义验证代码返回额外的(即不仅仅是字段=>错误消息)验证信息到 Controller 或 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11059030/