簡體   English   中英

如何將 FluentValidation 與 MetadataTypeAttribute 一起使用?

[英]How to use FluentValidation with MetadataTypeAttribute?

我正在開發 ASP.NET MVC 應用程序。 我發現 Fluent Validation 是一個很棒的驗證工具,而且它可以工作,但對於我當前的架構,它有一個缺點。 驗證器不關心元數據。 為了清楚起見,我在單獨的 class 上使用元數據。

Model

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

元數據 Model

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

誰能指出解決方案? 我需要用於標簽本地化的數據注釋(因此需要 DisplayAttribute)。

認為您需要編寫自己的顯示名稱解析器以進行流暢的驗證(猜測這應該放在您的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 ;
};

個人觀點

順便說一句,如果您只是為了清晰起見使用Metadata類,請不要使用它們! 如果您別無選擇(當實體類是從edmx生成的,並且您確實想以這種方式管理顯示名稱時),這可能是一個解決方案,但是如果沒有必要,我會真的避免使用它們。

public class CreateHireViewModel 
{
    [Display(Name = nameof(CreateHireViewModel.Title), ResourceType = typeof(Resource.HireResource.Hire))]
    public string Title { get; set; }
}

public class CreateHireViewModelValidator : AbstractValidator<CreateHireViewModel>
{
    public CreateHireViewModelValidator(IStringLocalizer<Resource.HireResource.Hire> l)
    {
        RuleFor(x => x.Title).NotEmpty().WithName(l[nameof(CreateHireViewModel.Title)]); 
        
        RuleFor(x => x.Title).Length(3, 50).WithName(l[nameof(CreateHireViewModel.Title)]);

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM