【问题标题】:Loading MetaData in Aspnet Core在 Aspnet Core 中加载元数据
【发布时间】:2018-09-29 21:45:25
【问题描述】:

我正在使用 AspNet Core 在 MVC 模板中构建一个项目。

我使用了实体框架,并且搭建了一个现有数据库。现在,我想为某个类添加一些数据注释,但我不想编辑由脚手架自动生成的类,所以我尝试使用元数据和覆盖现有方法 saveChanges

Scaffolding 自动生成的Users.cs

public partial class Users
{
    public int UserId { get; set; }
    ...
    // If I have [MaxLength(5, ErrorMessage = "Too short")] here, it works
    public string Email { get; set; }
}

UsersMetadata.cs(也尝试过 Users.Metadata.cs,否则没有任何改变)

[ModelMetadataType(typeof(UsersModelMetaData))]
public partial class Users { }

public class UsersModelMetaData
{
    [MaxLength(5, ErrorMessage = "Too short")]
    public string Email { get; set; }
}

MyContext : DbContext 类

public override int SaveChanges()
{
    var entities = from e in ChangeTracker.Entries()
                   where e.State == EntityState.Added
                       || e.State == EntityState.Modified
                   select e.Entity;
    foreach (var entity in entities)
    {               
    var validationContext = new ValidationContext(entity);
        Validator.ValidateObject(entity, validationContext, validateAllProperties: true);
    }

    return base.SaveChanges();
}

所以,即使这似乎是正确的解决方案(我已经搜索了一上午),它也不起作用:问题似乎是 UsersModelMetaData 中的数据注释未被读取,因为如果我将Data Annotation直接放到Users.cs文件中,方法saveChanges()会抛出异常。

我确实找到了这个解决方案 -> https://stackoverflow.com/a/30127682/6070423 AssociatedMetadataTypeTypeDescriptionProvider。

知道如何解决这个问题吗?

【问题讨论】:

  • 看看这是否有帮助(你没有展示你的用法,所以我不知道是不是这种情况):stackoverflow.com/a/37375987
  • @LuísAntunes 在那个问题中,答案只是使用 ModelMetadataType 而不是 MetadataType,但我已经在使用 ModelMetadataType.. 无论如何谢谢

标签: c# asp.net-mvc entity-framework asp.net-core


【解决方案1】:

所以,在我在 ASP.Net Core forum 上询问之后,感谢 Edward Z 的回答,我确实找到了一种方法。

基本上,我没有使用 ModelMetadataType 创建部分类,而是创建了一个包含所有需要验证的属性的类(因此,我将为每个由脚手架创建的类创建一个此类)。像这样的。

// Class generated by scaffolding
public partial class Users
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string Email { get; set; }
    }

// Class I did create. Notice that the name could be anything
//   but should contain at least "Users", which is the name of
//   the table generated by scaffolding.
// Also notice that isUnique is a Custom Attribute I've wrote.
public class UsersMetaData
    {
        [MinLength(2, ErrorMessage = " too short")]   
        public string UserName { get; set; }
        [MinLength(2, ErrorMessage = " too short psw")]
        public string Password { get; set; }
        [IsUnique(ErrorMessage = "Email already exists")]
        public string Email { get; set; }            
    }

之后,我创建了一个映射器,它将脚手架自动生成的类的实例映射到我创建的相关类。像这样的:

public static object MapEntity(object entityInstance)
   {
        var typeEntity = entityInstance.GetType();
        var typeMetaDataEntity = Type.GetType(typeEntity.FullName + "MetaData");

        if (typeMetaDataEntity == null)
            throw new Exception();

        var metaDataEntityInstance = Activator.CreateInstance(typeMetaDataEntity);

        foreach (var property in typeMetaDataEntity.GetProperties())
        {
            if (typeEntity.GetProperty(property.Name) == null)
                throw new Exception();

            property.SetValue(
                metaDataEntityInstance,
                typeEntity.GetProperty(property.Name).GetValue(entityInstance));
        }

        return metaDataEntityInstance;
    }

请注意,在第一行中,从实例的类型(即用户)开始,我通过在该名称中添加字符串“元数据”来检索我创建的相应类。然后,我所做的只是创建一个 UserMetaData 类的实例,并为 Users 实例分配相同的值。

最后,何时调用此映射器?在 SaveChanges() 中,当我进行验证时。那是因为验证是在 UserMetaData 类上进行的。

public override int SaveChanges()
        {
            var entities = from e in ChangeTracker.Entries()
                           where e.State == EntityState.Added
                               || e.State == EntityState.Modified
                           select e.Entity;
            foreach (var entity in entities)
            {
                var metaDataEntityInstance = EntityMapper.MapEntity(entity);
                var validationContext = new ValidationContext(metaDataEntityInstance);
                Validator.ValidateObject(
                    metaDataEntityInstance,
                    validationContext,
                    validateAllProperties: true);
            }

            return base.SaveChanges();
        }

这有点棘手,但一切正常!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2021-12-03
    • 2018-12-30
    • 1970-01-01
    • 2019-11-18
    相关资源
    最近更新 更多