0

总之,我正在尝试基于数据库字段在运行时创建特定于实例的数据注释属性。我现在所拥有的可以很好地创建初始模型,但是当模型被回发并且服务器验证发生时就会失败。

(我在视图模型中的集合中使用了相同的输入模型,但是必须对集合中的每个实例应用不同的验证......例如,输入的第一次出现可能被限制在 1-100 的范围内但在同一输入页面上提示的同一模型的下一次出现将是 1000-2000 的范围。另一个可能是日期,或者必须是 6 个字符长的字符串......)

我将解释我做了什么以及我的问题在哪里:

我继承DataAnnotationsModelMetadataProvider并提供了我自己的实现GetMetadataForProperty(这与验证问题没有任何关系......但是)

我继承DataAnnotationsModelValidatorProvider并提供了GetValidators. 我在这里要做的是根据我的数据库记录创建新属性,然后将这些属性传递给基本实现,以便相应地创建验证器。

但是...... GetValidators在 PROPERTY 级别调用......当使用我想要应用验证器的属性名调用它时,我需要找到该属性名的适用数据库记录,以便找出哪些属性我需要创建....但是...我无法仅从值字段的属性名中获取数据库记录的键......事实上,数据库键在父模型中......那我要怎么把握呢?!

我尝试使用静态变量(YUK)并在调用一个属性期间存储密钥,并在另一次调用我的值字段属性期间检索它......但是因为模型是单向序列化的,反序列化是相反的最终我的密钥与我所需的属性不同步。

为了增加一点复杂性,我还使用了自定义模型绑定器。我已经按照此处其他地方的建议覆盖了 CreateModel ,但是我找不到将元数据或附加值附加到我的输出模型的属性的方法....仅适用于模型本身....但是我该怎么做GetValidators 中的 MODEL 元数据/附加值需要一个 PROPERTY 吗?

所以......我的问题是双重的......

1) 谁能帮我从我的自定义模型绑定器中获取我的数据库密钥到我的 ValidationProvider 上的 GetValidators 方法?或者也许使用我的自定义元数据提供程序?

2) 是否有一种不同的、更简单的方法可以在运行时根据数据库记录创建验证器?

4

3 回答 3

1

我认为您使这比需要的复杂得多。您只需要使您的验证标准选择器成为您的视图模型的一部分。它们不一定必须显示(如果需要保留它们以用于回发目的,它们可以存储在隐藏中)。

然后你可以使用 FluentValidation 之类的东西来创建规则

RuleFor(model => model.myprop)
   .When(model => model.criteria == whatever)
   .GreaterThan(100)
   .LessThan(1000);

当您的属性必须在某个范围内时,标准是您用来选择的任何值。

这意味着您构建视图模型以包含用于验证规则选择的标准。

于 2014-04-17T17:15:05.970 回答
0

我也在FluentValidation 论坛上问过这个问题,这里缺乏答案以及反对使用 Fluent 的建议让我找到了自己的解决方案(我理解这几乎可以肯定意味着我正在做一些非常糟糕/不寻常的事情/不必要!)

我最终做的是在我的自定义模型绑定器的 CreateModel 方法中分配我的控制器静态变量,在那里我可以访问整个客户端模型,而不是尝试通过自定义 MetaDataProvider 来完成。这似乎工作得很好,让我走向我的应用程序的 v1。

虽然我对这个解决方案并不满意,但我会在未来几个月内重构整个领域,因此仍然会感谢人们对如何以通用方式实现动态验证的任何其他评论/想法。

于 2014-04-29T08:09:19.300 回答
0

我知道这是一个老问题,但我正在回答这个问题,以便许多其他人可以从中受益。

请参阅下面的文章,他们正在从 xml 加载属性

从 XML 加载 C# MVC .NET 数据注释属性,表单验证

我认为您可以采用相同的方法,而不是从 xml 中读取,您可以从数据库中读取并根据模型数据类型动态添加这些规则

您也可以参考以下方法

DataAnnotations 动态附加属性

于 2018-01-23T08:50:28.570 回答