[英]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中)。
警告
此解決方案僅嘗試解析顯示名稱 。
您將不再使用其他“驗證”屬性( Required
, StringLength
),因為您將通過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.