Asp.net mvc 4 将自定义参数传递给ValidationAttribute

Asp.net mvc 4 将自定义参数传递给ValidationAttribute,asp.net-mvc-4,Asp.net Mvc 4,我构建了一个自定义的ValidationAttribute,以便可以验证系统中唯一的电子邮件地址。但是,我希望以某种方式传入一个自定义参数,以便为验证添加更多逻辑 public class UniqueEmailAttribute : ValidationAttribute { public override bool IsValid(object value) { //I need the original value here so I won't valid

我构建了一个自定义的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());
    }
}
像这样

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;
    }
}

我建议使用@Oliver的答案(无论如何,我都会这么做),但我注意到您不想传递常数

那么像这样的怎么样

public static class MyConfig
{
    public static int MinStringLength { get; set; }
    public static int MaxStringLength { get; set; }
    public static SomeObject otherConfigObject { get; set; }
}
然后从验证中访问MyConfig.MinStringLength?
不过,我同意它并不太漂亮。

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

这里的问题是属性修饰不允许变量。 出现编译时错误:

非静态字段、方法或对象需要对象引用 财产

我是如何做到这一点的:

在控制器中

[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

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

创建自定义验证属性:

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; }
    }

有点,但我只能这样传递常数,对吗?我想传入原始值以与正在验证的值进行比较。是的,只传递常量。我不确定我是否明白你的问题。验证器只需验证一个属性的当前值,它不知道属性的任何过去值。这正是我要做的。因此,您只需在验证器中执行数据库调用,将当前值与原始值进行比较。还可以向模型中添加额外的“原始值”属性,并与该值进行比较。您应该能够通过ValidationContext访问对象的其他属性。ValidationContext将我指向了正确的位置。此链接包含我使用的方法:我尝试过这样做,但没有通过任何我认为会通过的内容。
    public class RequestModel 
    {
        public bool SomeProperty { get; set; }

        [SomeValidation(OtherProperty = "SomeProperty")]
        public DateTime? StartDate { get; set; }
    }