如何将参数传递给ValidationAttribute?

时间:2013-12-24 08:41:09

标签: c# asp.net-mvc data-annotations

我有一个自定义ValidationAttribute,它检查是否已存在其他用户。 为此它需要访问我的数据访问层,一个实例由Unity注入我的控制器

如何将此(或其他任何内容)作为参数传递到我的自定义验证器中?

这可能吗?即我正在创建Dal,这应该是一个参数

public class EmailIsUnique : ValidationAttribute
    {
        private string _errorMessage = "An account with this {0} already exists";

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DataAccessHelper Dal = new DataAccessHelper(SharedResolver.AppSettingsHelper().DbConnectionString); //todo, this is way too slow
            bool isValid = true;
            if(value == null) {
                isValid = false;
                _errorMessage = "{0} Cannot be empty";
            } else {
                string email = value.ToString();
                if (Dal.User.FindByEmail(email) != null)
                {
                    isValid = false;
                }
            }

            if (isValid)
                return ValidationResult.Success;
            else
                return new ValidationResult(String.Format(_errorMessage, validationContext.DisplayName));
        }
    }

3 个答案:

答案 0 :(得分:4)

我不太确定你能否将运行时参数传递给你的属性。

您可以使用DependencyResolver.Current.GetService<DataAccessHelper>()来解决您的dal(假设您已注册DataAccessHelper)

您可能更有可能将DataAccessHelper注册为IDataAccessHelper或其他什么?在这种情况下,你打电话给GetService<IDataAccessHelper>

public class EmailIsUnique : ValidationAttribute
{
    private string _errorMessage = "An account with this {0} already exists";

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        IDataAccessHelper Dal = DependencyResolver.Current.GetService<IDataAccessHelper>(); // too slow
        bool isValid = true;
        if(value == null) {
            isValid = false;
            _errorMessage = "{0} Cannot be empty";
        } else {
            string email = value.ToString();
            if (Dal.User.FindByEmail(email) != null)
            {
                isValid = false;
            }
        }

        if (isValid)
            return ValidationResult.Success;
        else
            return new ValidationResult(String.Format(_errorMessage, validationContext.DisplayName));
    }
}

public class EmailIsUnique : ValidationAttribute
{
    [Dependency]
    public IDataAccessHelper DataAccess {get;set;}

    private string _errorMessage = "An account with this {0} already exists";

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {

        bool isValid = true;
        if(value == null) 
        {
            isValid = false;
            _errorMessage = "{0} Cannot be empty";
        } 
       else 
       {
            string email = value.ToString();
            if (DataAccess.User.FindByEmail(email) != null)
            {
                isValid = false;
            }
        }

        if (isValid)
            return ValidationResult.Success;
        else
            return new ValidationResult(String.Format(_errorMessage, validationContext.DisplayName));
    }
}

答案 1 :(得分:1)

您可能正在寻找房产注资。看看this帖子。 第一个解决方案是创建支持依赖注入的自定义筛选器提供程序。

第二个解决方案是使用Service Locator模式并在属性构造函数中获取服务实例。

答案 2 :(得分:0)

是的。您可以传递在Model类中使用的参数,如下所示:

[EmailIsUnique()]
public string Email {get; set;}

所以这会自动将Email作为参数传递并检查值。