21

我构建了一个自定义 ValidationAttribute,因此我可以验证系统中的唯一电子邮件地址。但是,我想以某种方式传入一个自定义参数,以便为我的验证添加更多逻辑。

public class UniqueEmailAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        //I need the original value here so I won't validate if it hasn't changed.
        return value != null && Validation.IsEmailUnique(value.ToString());
    }
}
4

4 回答 4

53

像这样?

public class StringLengthValidatorNullable : ValidationAttribute
{
    public int MinStringLength { get; set; }
    public int MaxStringLength { get; set; }

    public override bool IsValid(object value)
    {
        if (value == null)
        {
            return false;
        }
        var length = value.ToString().Length;

        if (length < MinStringLength || length >= MaxStringLength)
        {
            return false;
        }
        return true;
    }
}

采用:

[StringLengthValidatorNullable(MinStringLength = 1, MaxStringLength = 16)]
public string Name {get; set;}
于 2013-02-14T16:04:56.443 回答
4

您还可以传递同一模型中其他属性的参数。

创建自定义验证属性:

public class SomeValidationAttribute : ValidationAttribute
{
    //A property to hold the name of the one you're going to use.
    public string OtherProperty { get; set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //Get the value of the property using reflection.
        var otherProperty = validationContext.ObjectType.GetProperty(OtherProperty);
        var otherPropertyValue = (bool)otherProperty.GetValue(validationContext.ObjectInstance, null);

        if (value != null && otherPropertyValue)
        {
            return ValidationResult.Success;
        }

        return new ValidationResult("Invalid property message.");
    }
}

然后传递您要使用的属性的名称。

    public class RequestModel 
    {
        public bool SomeProperty { get; set; }

        [SomeValidation(OtherProperty = "SomeProperty")]
        public DateTime? StartDate { get; set; }
    }
于 2018-03-14T14:34:22.827 回答
1

有一个类似的要求,我必须将值传递给自定义属性。

这里的问题是 Attribute 装饰不允许variables。你得到编译时错误:

非静态字段、方法或属性需要对象引用

这是我能够做到的:

在控制器中

[FineGrainAuthorization]
public class SomeABCController : Controller
{
    public int SomeId { get { return 1; } }
}

在属性

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class FineGrainAuthorizationAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        ControllerBase callingController = filterContext.Controller;
        var someIdProperty = callingController.GetType().GetProperties().Where(t => t.Name.Equals("SomeId")).First();
        int someId = (int) someIdProperty.GetValue(callingController, null);
    }
}

记住里面的字符串.Name.Equals("SomeId")必须大小写匹配声明public int SomeId

于 2017-11-29T21:21:34.093 回答
0

我会建议像@Oliver's answer之类的东西(无论如何,这就是我要做的),但后来我注意到你不想传递常量。

那么这样的事情呢?

public static class MyConfig
{
    public static int MinStringLength { get; set; }
    public static int MaxStringLength { get; set; }
    public static SomeObject otherConfigObject { get; set; }
}

然后MyConfig.MinStringLength从验证中访问?不过,我同意它不太漂亮。

于 2013-02-21T14:57:47.100 回答