【问题标题】:How to use FluentValidation with MetadataTypeAttribute?如何将 FluentValidation 与 MetadataTypeAttribute 一起使用?
【发布时间】:2016-09-16 09:06:12
【问题描述】:

我正在开发 ASP.NET MVC 应用程序。我发现 Fluent Validation 是一个很棒的验证工具,它可以工作,但在我当前的架构中,它有一个缺点。验证器不关心元数据。为了清楚起见,我在单独的类中使用元数据。

型号

[MetadataType(typeof(DocumentEditMetadata))]
[Validator(typeof(DocumentValidator))]
public class DocumentEditModel
{
    public string DocumentNumber { get; set; }
    (etc...)
}

元数据模型

public class DocumentEditMetadata
{
    [Required]
    [StringLength(50)]
    [Display(ResourceType = typeof(Label), Name = "DocumentNumber")]
    public string DocumentNumber { get; set; }
    (etc...)
}

谁能指出一个解决方案?我需要用于标签本地化的数据注释(因此是 DisplayAttribute)。

【问题讨论】:

    标签: c# asp.net asp.net-mvc fluentvalidation


    【解决方案1】:

    认为您需要编写自己的显示名称解析器以进行流畅的验证(猜想这应该放在您的 global.asax 中)。

    注意

    此解决方案只是尝试解析显示名称

    不应再使用您的其他“验证”属性(RequiredStringLength),因为您将使用 FluentValidation 进行管理。

    ValidatorOptions.DisplayNameResolver = (type, memberInfo, expression) =>
    {
          //this will get in this case, "DocumentNumber", the property name. 
          //If we don't find anything in metadata / resource, that what will be displayed in the error message.
          var displayName = memberInfo.Name;
          //we try to find a corresponding Metadata type
          var metadataType = type.GetCustomAttribute<MetadataTypeAttribute>();
          if (metadataType != null)
          {
               var metadata = metadataType.MetadataClassType;
               //we try to find a corresponding property in the metadata type
               var correspondingProperty = metadata.GetProperty(memberInfo.Name);
               if (correspondingProperty != null)
               {
                    //we try to find a display attribute for the property in the metadata type
                    var displayAttribute = correspondingProperty.GetCustomAttribute<DisplayAttribute>();
                    if (displayAttribute != null)
                    {
                         //finally we got it, try to resolve the name !
                         displayName = displayAttribute.GetName();
                    }
              }
          }
          return displayName ;
    };
    

    个人观点

    顺便说一句,如果您只是为了清晰而使用元数据类,请不要使用它们! 如果您别无选择(当实体类从 edmx 生成并且您真的想以这种方式管理显示名称时),这可能是一个解决方案,但如果没有必要,我真的会避免使用它们。

    【讨论】:

    • 感谢您的帮助和意见。它适用于规则,但是当我没有指定规则(非空值不需要)时,它使用默认解析器。我找不到类似的调整
    • FluentValidationModelValidatorProvider 似乎在需要时添加了“必需”,但用户没有自己指定(流利)。不幸的是,在 FluentValidationPropertyValidator 的 ctor 中,存在创建 PropertyRule 的默认逻辑,并且它会覆盖在 PropertyRule ctor 中正确设置的 DisplayName。我认为这是一个错误。 github.com/JeremySkinner/FluentValidation/blob/…
    • 您的意思是问题出在您为不可为空的属性设置空值时?这与 FluentValidation 无关,而是来自 Mvc 的默认模型绑定器。
    • 我不是这个意思。这是通缉行为。问题是 FluentValidation 逻辑不使用默认的 DisplayNameResolver 而是硬编码的 _defulatDisplayNameResolver (检查参考)。结果,我得到了默认显示名称(例如属性 DocumentNumber 的“文档编号”),而不是触发我事先指定的 ValidatorOptions.DisplayNameResolver。
    • 你可以看看这个,也许:stackoverflow.com/questions/9746186/…
    猜你喜欢
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 2011-02-22
    • 2021-01-02
    • 1970-01-01
    • 2023-03-13
    • 2014-09-25
    • 2016-01-30
    相关资源
    最近更新 更多