如何将 FluentValidation 与 MetadataTypeAttribute 一起使用?
How to use FluentValidation with MetadataTypeAttribute?
我正在开发 ASP.NET MVC 应用程序。我发现 Fluent Validation 是一个很棒的验证工具,而且它可以工作,但对于我当前的架构,它有一个缺点。验证器不关心元数据。为了清楚起见,我在单独的 class 上使用元数据。
型号
[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)。
认为您需要编写自己的显示名称解析器以进行流畅的验证(猜测这应该放在您的 global.asax 中)。
注意
此解决方案仅尝试解析显示名称。
不应再使用您的其他 "validation" 属性(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 ;
};
个人观点
顺便说一下,如果您只是为了 清晰度 使用元数据 类,请不要使用它们!
如果您别无选择(当实体 类 是从 edmx 生成的并且您真的想以这种方式管理显示名称时),这可能是一个解决方案,但如果没有必要,我真的会避免使用它们。
我正在开发 ASP.NET MVC 应用程序。我发现 Fluent Validation 是一个很棒的验证工具,而且它可以工作,但对于我当前的架构,它有一个缺点。验证器不关心元数据。为了清楚起见,我在单独的 class 上使用元数据。
型号
[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)。
认为您需要编写自己的显示名称解析器以进行流畅的验证(猜测这应该放在您的 global.asax 中)。
注意
此解决方案仅尝试解析显示名称。
不应再使用您的其他 "validation" 属性(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 ;
};
个人观点
顺便说一下,如果您只是为了 清晰度 使用元数据 类,请不要使用它们! 如果您别无选择(当实体 类 是从 edmx 生成的并且您真的想以这种方式管理显示名称时),这可能是一个解决方案,但如果没有必要,我真的会避免使用它们。