【问题标题】:MVC : How to use database to drive validation attributes, or ALTERNATIVES?MVC:如何使用数据库来驱动验证属性或替代方案?
【发布时间】:2014-04-17 15:11:06
【问题描述】:

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

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

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

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

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

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

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

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

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

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

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

【问题讨论】:

  • 快速谷歌搜索;这会做你想做的事吗? fluentvalidation.codeplex.com/wikipage?title=mvc
  • 我看过 FluentValidation,但同样的问题....如何使用来自数据库字段的动态值构建“RuleFor”?我看不到按实例执行此操作的方法。还查看了企业验证块,但又一次......我需要特定于实例的规则,而不是特定于模型的......
  • @DaveR - 我想你很困惑。属性适用于类型,而不是实例。它们被编译到代码中,因此它们是在编译时定义的,而不是在运行时定义的。
  • 不,没有混淆。是的,我知道您通常会在编译时创建属性,但我的验证标准不是基于类型的,而是基于实例的......所以......我在运行时使用我自己的 DataAnnotationsModelValidatorProvider 版本添加它们,因为我在问题中说。
  • @DaveR - 没有“通常”。属性总是在编译时添加,不能在运行时添加到现有类。您可以在运行时使用 emit 构建属性,并将它们添加到您使用 emit 构建的类中,但是您自己做所有事情,这不是您想要的。

标签: asp.net-mvc-4 metadata data-annotations custom-model-binder


【解决方案1】:

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

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

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

条件是当您的属性必须在特定范围内时您用来选择的任何值。

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

【讨论】:

  • 我可以看到这很有潜力。我会深入研究并进一步调查。
【解决方案2】:

我也在FluentValidation forums 上问过这个问题,这里没有答案以及反对使用 Fluent 的建议让我找到了自己的解决方案(我明白这几乎可以肯定意味着我正在做一些真正的事情坏的/不寻常的/不必要的!)

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

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

【讨论】:

    【解决方案3】:

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

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

    Loading C# MVC .NET Data Annotation Attributes From XML, Form Validation

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

    你也可以参考下面的方法

    DataAnnotations dynamically attaching attributes

    【讨论】:

      猜你喜欢
      • 2010-11-21
      • 2017-04-23
      • 2015-09-30
      • 1970-01-01
      • 2023-02-03
      • 1970-01-01
      • 2014-07-29
      • 2013-04-09
      • 1970-01-01
      相关资源
      最近更新 更多