Web API中的动态验证

时间:2014-12-26 17:33:18

标签: c# asp.net validation asp.net-web-api

我希望根据数据库中的值验证特定请求。这是一个复杂的场景,但我会尝试在一个例子中简化它。

说我有以下型号:

public class CustomerModel 
{
    public int AgencyId { get; set; }

    public string Name { get; set; }

    public int Age { get; set; }
}

当POST请求进入时,我需要拨打电话以获得通过AgencyId的某些要求。

var requirements = _repository.GetRequirementsForAgency(model.AgencyId);

我将从数据库中获取的信息将告诉我哪些属性是必需的,每个机构可能会有所不同。例如,一个机构可能需要姓名和年龄,而另一个机构可能只需要姓名。需求对象看起来像这样:

public class Requirement
{
    public string PropertyName { get; set; }

    public bool IsRequired { get; set; }
}

那么,我的问题是在将此模型提交到数据库之前验证该模型的最佳方法是什么?理想情况下,我想让原子能机构有能力改变这些要求,因此,如果可能的话,我想避免硬编码验证。

我的第一个想法是调用一个需求列表然后对每个按PropertyName搜索的需求做一个foreach,然后检查是否有值,但我不确定这是否是最好的方法。

然后我查看了数据注释,但没有找到在运行时添加属性的方法。

1 个答案:

答案 0 :(得分:1)

您可以使用Fluent Validation library并实施自定义验证器

public class CustomerModelValidator : AbstractValidator<CustomerModel>
{
    private readonly IRepository _repository;

    public RegisterModelValidator(IRepository repository)
    {
        this._repository= repository;

        RuleFor(x => x.AgencyId).GreaterThan(0).WithMessage("Invalid AgencyId");
        RuleFor(x => x.Age).GreaterThan(0).WithMessage("Invalid Age");
        Custom(c =>
                {
                    var requirements = _repository.GetRequirementsForAgency(model.AgencyId);
                    \\validate each property according to requirements object.
                    \\if (Validation fails for some property)
                        return new ValidationFailure("property", "message");
                    \\else
                    return null;
                });
    }
}

如果在项目中使用依赖注入(我强烈建议),则必须将相关的IRepository注入属性。否则,您只需在属性中创建/使用特定的存储库。

非常好的一点是,properly register your validator当您使用默认if (ModelState.IsValid)支票验证模型