根据收到的值将值传递给属性

pass value to attribute based on received value

我正在使用 C# 4.5 web api 类型的项目。

当收到来自客户端的 HttpPost 请求时,我想验证请求字段。 问题是输入验证取决于输入本身,或者更具体地说,取决于提供的枚举。

假设我有以下 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}

我还写了 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;
    }
}

问题是当我尝试调用 [myEnumCheckName(myEnum) 时它说:

Cannot access static property myEnum in static context.

是否可以访问 instance/current 上下文字段值?

谢谢。

澄清

我想验证 NameEmail 属性,这是一般的想法。 现在,如果 Filter 值为 ByEmail,我不介意 Name 是否为空,反之亦然。 这样,我就不必编写处理请求两次的相同方法。

您无法使用 ComponentModel.DataAnnotations 中的内置验证框架实现这种验证逻辑。如果您想根据其他属性值自动验证您的 class 属性,那么您应该切换到具有此类功能的不同验证框架。

我建议您查看 FluentValidation,并为您的 classes 创建自定义验证器,以便轻松处理您描述的复杂情况。例如,您可以为 A class 创建类似于以下验证器的验证器:

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

想要了解更多关于如何将FluentValidation集成到Web Api中,您可以参考下面的教程(如果您不想提供验证器,可以忽略Ninject部分通过依赖注入框架):
http://sergeyakopov.com/restful-validation-with-asp-net-web-api-and-fluentvalidation/