0

I would like to know if it may be possible to use a generic class with a Custom Validator I have made. Here is the original code of the Custom Validator :

public class UniqueLoginAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value,
              ValidationContext validationContext)
    {
        ErrorMessage = string.Format("The Username {0} is already used.", value.ToString());
        //Validation process
    }
}

I would like to have something like that instead :

public class UniqueLoginAttribute<T> : ValidationAttribute where T : IManage
{
    protected override ValidationResult IsValid(object value,
              ValidationContext validationContext)
    {
        ErrorMessage = string.Format("The Username {0} is already used.", value.ToString())
        //EDIT
        new T().DoSomething();
        //End of Validation process
    }
}



The question is, how can I use such a Custom validator with one of my models ? Is it even possible ? Here is what I would like to achieve :

public class UserModel : IManage
{
    public int ID { get; set; }

    [UniqueLogin<UserModel>]
    public string UserName { get; set; }

    public int Age { get; set; }
}


Is there a way to use generics with that kind of custom validation ?

Glad
  • 147
  • 1
  • 11
  • `T.DoSomething()` will not work. You cannot call a static method through an interface, you need an instance of T. – Kris Vandermotten Sep 15 '14 at 13:07
  • @KrisVandermotten : I've tried what I wrote, it actually doesn't compile. How can I involve an instance of T in the code of my validator ? And Then, how may I use it in my model ? – Glad Sep 15 '14 at 13:11
  • First of all, if it doesn't compile, read (and post) the compilation error message. And BTW, I know it doesn't compile, see my previous comments. Secondly, `new T().DoSomething();` might be a solution, you would then have to add the `new` constraint to the generic type of course. Then again, you want to do this with a `UserModel`, which presumably models a specific user. That wouldn't work. Maybe you need something like `[UniqueLogin]`, although I must admit that I do wonder why you actually do need this. – Kris Vandermotten Sep 15 '14 at 13:18
  • Well, the part I am concerned about is how to make something like [UniqueLogin] work. It seems like it's not possible to use generics with a Validation Attribute. Maybe there is another way ? I need this because I want to use the same Custom Validator (which checks unicity of a value) for a several number of similar models. – Glad Sep 15 '14 at 13:23
  • Generic Attributes are not possible. See also http://stackoverflow.com/questions/294216/why-does-c-sharp-forbid-generic-attribute-types. So you would have to do [UniqueLogin(typeof(UserService))] – Kris Vandermotten Sep 15 '14 at 14:11

1 Answers1

1

Generic attributes are not possible in C#, see also Why does C# forbid generic attribute types?

Here's a workaround:

public class UniqueLoginAttribute : ValidationAttribute
{
    public UniqueLoginAttribute(Type managerType)
    {
        this.ManagerType = managerType;
    }

    public Type ManagerType { get; private set; }

    protected override ValidationResult IsValid(object value,
          ValidationContext validationContext)
    {
        IManage manager = Activator.CreateInstance(this.ManagerType) as IManage;

        return manager.Validate(value);
    }
}

Usage:

[UniqueLoginAttribute(typeof(UserService))]
Community
  • 1
  • 1
Kris Vandermotten
  • 10,111
  • 38
  • 49