如何在MetadataTypeAttribute中使用FluentValidation?

时间:2016-09-16 09:06:13

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

我正在开发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)。

1 个答案:

答案 0 :(得分:1)

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

<强>注意

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

您的其他&#34;验证&#34;不应再使用属性(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生成并且您真的想以这种方式管理显示名称时)它可能是一个解决方案,但如果没有必要,我会真的避免使用它们。