【问题标题】:Handling Data Annotation Validation with Custom ValidationResult使用自定义 ValidationResult 处理数据注释验证
【发布时间】:2013-04-09 13:29:50
【问题描述】:

我有一个像这样的自定义 ValidationAttribute:

public class ReceiverRegion : ValidationAttribute { private RegionService regionService; private CityService cityService; public ReceiverRegion() : base("Incorrect region code") { this.regionService = new RegionService(); this.cityService = new CityService(); } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { int regionId = Convert.ToInt32(value); int plate = Convert.ToInt32((validationContext.ObjectInstance as CorporateOrderItem).ReceiverCity); int productGroupId = Convert.ToInt32(validationContext.Items["productGroup"].ToString()); if (!CheckReceiverRegionExistence(regionId, plate, productGroupId)) { IEnumerable regions = this.regionService.GetList(cityService.GetByPlate(plate).PKCityId); return new CorporateOrderValidationResult(base.ErrorMessage, regions.Select(r=>r.Name)); } return CorporateOrderValidationResult.Success; } private bool CheckReceiverRegionExistence(int plate, int regionId, int productGroup) { return !(regionService.GetByCityAndRegionIdForProductGroup(plate, regionId, productGroup) == null); } }

但正如您在 IsValid 方法中看到的,我试图返回一个继承自 ValidationResult 的自定义对象。我的问题是,我无法访问我的 CorporateOrderValidationResult 实例的额外成员,因为 IsValid 返回基本 ValidationResult 类型。下面是我调用 validate 并获取 ValidationResult 集合作为返回值的代码。


List results = new List();
bool isValid = Validator.TryValidateObject(instance, context, results, true);

我尝试将结果对象转换为 List<CorporateOrderValidationResult>,但无论我尝试什么(例如 --> item as CorporateOrderValidationResultresults.OfType<CorporateOrderValidationResult>()(CorporateOrderValidationResult)item) 我要么得到 InvalidCastException 或 null 值。有没有可能的方法将此结果列表转换为我的自定义结果类列表?谢谢...

【问题讨论】:

    标签: c# validation inheritance attributes base


    【解决方案1】:

    我尝试重现此行为,但一切正常:

    public class TestClass
    {
        [TestValidation]
        public string TestProp { get; set; }
    }
    
    public class TestValidationAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return new TestResult();
        }
    }
    
    public class TestResult : ValidationResult
    {
        public TestResult()
            : base("test")
        {
        }
    }
    

    验证代码:

    var instance = new TestClass();
    var context = new ValidationContext(instance, null, null);
    var results = new List<ValidationResult>();
    bool isValid = Validator.TryValidateObject(instance, context, results, true);
    //Contains one instance of TestResult
    var customResults = results.OfType<TestResult>().ToArray();
    

    【讨论】:

    • 您在此处尝试的代码与我的情况完全相同。但是当我调用 var customResults = results.OfType().ToArray();即使集合中有一些 ValidationResult 对象,也没有返回任何项目。我会再试一次。
    【解决方案2】:

    我知道这是个老问题,但是当您要求自定义 ValidationResult 类时,Google 的第一个结果是。 Vyacheslav Volkov 提出的示例有效,但为什么呢?

    我今天花了几个小时试图让我的代码正常工作 - 关键是:

    public TestResult(): base ("test")

    我根本不打算使用错误消息,我有自己的结构,所以我这样写了我的ctor:

    public TestResult() : base("") - 发送到基类的空字符串会产生后果,文档中没有提到。 TryValidate() 方法不会将我们的对象插入到results 集合中,因为它是由我们的IsValid() 版本返回的,但会为该字段构建一个带有默认错误消息的新对象,例如"Field " + fieldName + " is Invalid" 并用它代替那个我们想要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      相关资源
      最近更新 更多