-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.

4

1 回答 1

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/

于 2016-05-12T14:34:22.613 回答