-1

Im using C# 4.5 web api type project.

When receiving HttpPost requests from clients i want to validate the request fields. The issue is that the input validation is depended on the input itself, or to be more specific, depends on provided enum.

Assuming I have the following class:

public class A 
{
     public myEnum Filter{set;get;}

     [myEnumCheckName(Filter)]
     public string Name {set;get;}

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

public enum myEnum {ByName = 1, ByEmail = 2}

And also I wrote 2 validatorAttributes:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class myEnumCheckName : ValidationAttribute
{
    private readonly someNameValidator _validator = new someNameValidator();
    private readonly myEnum _filter;

    public myEnumCheckName(myEnum filter)
    {
        _filter = filter;
    }

    public override bool IsValid(object value)
    {
        if (_filter == myEnum.ByName)
            return _validator.IsValid(value);

        return true;
    }
}

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class myEnumCheckEmail : ValidationAttribute
{
    private readonly someEmailValidator _validator = new someEmailValidator();
    private readonly myEnum _filter;

    public myEnumCheckEmail(myEnum filter)
    {
        _filter = filter;
    }

    public override bool IsValid(object value)
    {
        if (_filter == myEnum.ByEmail)
            return _validator.IsValid(value);

        return true;
    }
}

Problem is that when I try call [myEnumCheckName(myEnum) it says:

Cannot access static property myEnum in static context.

Is there anyway to access the instance/current context field values?

Thanks.

CLARIFICATION

I want to validate the Name and Email properties, thats the general idea. Now, I dont mind if Name would be null if the Filter value will be ByEmail and vice-versa. this way, I dont have to write the same method that handles the request twice.

Ori Refael
  • 2,888
  • 3
  • 37
  • 68
  • Please read [ask] and provide a [mcve]. Your first code block is full of syntax errors. Also, research the _actual_ error you receive. The problem is that you have a member name that is equal to the enum name. Use the enum's full namespace in the attribute. – CodeCaster May 12 '16 at 13:51
  • It's not clear what you are trying to achieve. Do you want to check if the `Name` field is not empty, but only when the provided enum value equals to `ByName`? Please clarify. Also, as a side note, your attribute declarations are missing a closing square bracket, so CodeCaster is right. – Federico Dipuma May 12 '16 at 14:14
  • @FedericoDipuma you understood it well. and CodeCaster is right when i missed 2 brackets but it is not a reason to downvote a question and claim that only because of those 2 brackets my entire question is not well written. Also, added clarification in question – Ori Refael May 12 '16 at 14:20
  • 1
    Class `A` also has an incomplete property declaration `public myEnum {set;get;}`. Anyway no, you cannot use variables in attributes, they must be compile-time constants. – CodeCaster May 12 '16 at 14:26

1 Answers1

1

You cannot achieve this kind of validation logic using the built-in Validation framework from ComponentModel.DataAnnotations. If you want to automatically validate your class properties based on other properties values, then you should switch to a different validation framework that has such feature.

I suggest you to look into FluentValidation, and create custom validators for your classes that can easily handle complex situations like the one you described. You could, for example, create a validator for your A class similar to the following one:

public class AValidator: AbstractValidator<A>
{
    public AValidator()
    {
        RuleFor(a => a.Name)
            .NotEmpty()
            .When(c => c.Filter == myEnum.ByName);

        RuleFor(a => a.Email)
            .NotEmpty()
            .When(c => c.Filter == myEnum.ByEmail);
    }
}

To know more on how to integrate FluentValidation into Web Api you may refer to the following tutorial (you may ignore the Ninject part if you do not want to provide validators through a dependency injection framework):
http://sergeyakopov.com/restful-validation-with-asp-net-web-api-and-fluentvalidation/

Federico Dipuma
  • 17,655
  • 4
  • 39
  • 56