0

我们使用 DB-first 方法在 .NET 核心应用程序中生成模型。DataAnnotations 被放在“伙伴”元数据类中,以避免写入自动生成的文件。当控制器调用 TryValidateModel 时,一切正常,需要 Name 属性。

public partial class User
{
    public string Name { get; set; }
}

[ModelMetadataType(typeof(UserMetaData))]
public partial class User : IValidatableObject
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { }
}

public class UserMetaData
{
    [Required]
    public string Name { get; set; }
}

在应用程序的服务层上,我们希望实现额外的验证,它还检查对象在数据注释方面是否有效。这是通过 Validator.TryValidateObject() 成功调用 Validate 方法完成的,但忽略数据注释 - 用户是有效的,即使名称为空。

TL;DR:MVC(Web 项目)知道如何考虑通过 ModelMetadataType 属性放入“伙伴”类中的数据注释,而服务层项目则不知道。

我以为我在这里找到了答案,但似乎 TypeDescriptor.AddProviderTransparent 不适用于 .net核心应用程序。

任何想法将不胜感激。

4

1 回答 1

0

I really hoped for a one line solution :)

I abused ashrafs answer to his own question like so:

var metadataAttr = typeof(T).GetCustomAttributes(typeof(ModelMetadataTypeAttribute), true).OfType<ModelMetadataTypeAttribute>().FirstOrDefault();
if (metadataAttr != null)
{
    var metadataClassProperties = TypeDescriptor.GetProperties(metadataAttr.MetadataType).Cast<PropertyDescriptor>();
    var modelClassProperties = TypeDescriptor.GetProperties(typeof(T)).Cast<PropertyDescriptor>();

    var errs =
        from metaProp in metadataClassProperties
        join modelProp in modelClassProperties
        on metaProp.Name equals modelProp.Name

        from attribute in metaProp.Attributes.OfType<ValidationAttribute>()
        where !attribute.IsValid(modelProp.GetValue(model))
        select new ValidationResult(attribute.FormatErrorMessage(Reflector.GetPropertyDisplayName<T>(metaProp.Name)), new[] { metaProp.Name });

    validationResults.AddRange(errs);
}
于 2020-03-17T18:16:45.123 回答