简体   繁体   English

使用Custom ValidationResult处理数据注释验证

[英]Handling Data Annotation Validation with Custom ValidationResult

I have a custom ValidationAttribute like this : 我有一个像这样的自定义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);
        }
    }

But as you can see in IsValid method, I'm trying to return a custom object which inherits from ValidationResult. 但正如您在IsValid方法中看到的那样,我正在尝试返回一个继承自ValidationResult的自定义对象。 My problem is, I can't access the extra members of my CorporateOrderValidationResult instance since IsValid returns the base ValidationResult type. 我的问题是,我无法访问我的CorporateOrderValidationResult实例的额外成员,因为IsValid返回基本的ValidationResult类型。 Below is the code where I call validate and get a collection of ValidationResult as return value. 下面是我调用validate并获取ValidationResult集合作为返回值的代码。


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

I tried to cast results object to List<CorporateOrderValidationResult> , but no matter what I try(for instance --> item as CorporateOrderValidationResult or results.OfType<CorporateOrderValidationResult>() or (CorporateOrderValidationResult)item) I either get InvalidCastException or null value. 我试图将结果对象转换为List<CorporateOrderValidationResult> ,但无论我尝试什么(例如 - > item as CorporateOrderValidationResultresults.OfType<CorporateOrderValidationResult>()(CorporateOrderValidationResult)item)我要么获得InvalidCastException或null值。 Is there a possible way to convert this list of result to a list of my custom result class? 有没有办法将此结果列表转换为我的自定义结果类列表? Thanks... 谢谢...

I tried to reproduce this behavior, but everything works as expected: 我试图重现这种行为,但一切都按预期工作:

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")
    {
    }
}

Code for validation: 验证代码:

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();

I know this is old question, but first result in Google when you ask for custom ValidationResult class. 我知道这是一个老问题,但当您要求自定义ValidationResult类时,首先会在Google中产生结果。 Example presented by Vyacheslav Volkov works, but why? Vyacheslav Volkov的例子有效,但为什么呢?

I spent few hours today trying to make my code working - the key line is: 我今天花了几个小时试图让我的代码工作 - 关键是:

public TestResult(): base ("test")

I was not going to use error message at all, I had my own structure for this so I wrote my ctor like this: 我根本不会使用错误信息,我有自己的结构,所以我写了这样的ctor:

public TestResult() : base("") - empty string sent to base class has consequences, that are not mentioned in documentation. public TestResult() : base("") - 发送到基类的空字符串有后果,文档中没有提到。 TryValidate() method will not insert our object into results collection as it is returned by our version of IsValid() , but will build new one with default error message for this field, like "Field " + fieldName + " is Invalid" and put it instead of the one we want. TryValidate()方法不会将我们的对象插入到我们的IsValid()版本返回的results集合中,但会为此字段构建一个带有默认错误消息的新对象,例如"Field " + fieldName + " is Invalid"并放入它而不是我们想要的那个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM