从自定义验证器中的验证上下文的基本类型获取值

时间:2014-02-07 13:36:47

标签: c# validation asp.net-mvc-4 c#-4.0

我正在尝试编写自己的验证属性,但是我无法从继承的类中获取属性的值。这是我的代码:

protected override ValidationResult IsValid(object value, ValidationContext context)
{
    if (context.ObjectType.BaseType == typeof(AddressModel))
    {
        PropertyInfo property = context.ObjectType.BaseType.GetProperty(_propertyName);

        // this is the line i'm having trouble with:
        bool isRequired = (bool)property.GetValue(context.ObjectType.BaseType); 

        return base.IsValid(value, context);
    }

    return ValidationResult.Success;
}

我不知道我想要传递给GetValue的是什么,因为它期待一个对象,但我传入的所有东西都给了我属性类型与目标异常不匹配

我不得不转到基类型,因为我试图从继承的类中获取属性的值,而context.ObjectInstance不包含必要的属性

3 个答案:

答案 0 :(得分:7)

您可以简单地将对象转换为AddressModel,然后像这样使用它。

protected override ValidationResult IsValid(object value, ValidationContext context)
{
    var addressModel = context.ObjectInstance as AddressModel
    if (addressModel != null)
    {
        // Access addressModel.PROPERTY here

        return base.IsValid(value, context);
    }

    return ValidationResult.Success;
}

context.ObjectInstanceobject类型而不是模型的类型,因为验证框架不是为了显式验证模型而创建的,而是正确的对象实例。一旦它被铸造,你可以正常使用它。

作为旁注,您使用property.GetValue(context.ObjectType.BaseType)收到错误的原因是因为GetValue方法需要您正在调用其属性的对象的实例。

答案 1 :(得分:1)

您可以将ObjectInstance投射到其基本类型,因此您可以尝试这样做:

protected override ValidationResult IsValid(object value, ValidationContext context)
{
    if (context.ObjectType.BaseType == typeof(AddressModel))
    {
        AddressModel model = (AddressModel)context.ObjectInstance;
        PropertyInfo property = typeof(AddressModel).GetProperty(_propertyName);

        bool isRequired = (bool)property.GetValue(model, null); 

        //OR YOU CAN INTERROGATE THE MODEL DIRECTLY
        var x = model.SomeProperty == true;

        return base.IsValid(value, context);
    }

    return ValidationResult.Success;
}

答案 2 :(得分:0)

您应该软转换为所需的对象类型并保存自己的反射,这在编译时知道所需的类型时是不必要的。

此代码假定您将自定义属性放在模型的类定义上(而不是单个属性)。 value将是您放置属性的属性或类的实例:

protected override ValidationResult IsValid(object value, ValidationContext context)
{
    var addressModel = value as AddressModel;
    if (addressModel != null)
    {
        // Do some stuff against addressModel here to determine if valid...

        return base.IsValid(value, context);
    }

    return ValidationResult.Success;
}