我正在使用AspNet Core在MVC模板中构建项目。
我使用了实体框架,并搭建了一个现有的数据库。现在,我想向某些类添加一些数据注释,但是我不想编辑由脚手架自动生成的类,因此我尝试使用元数据和现有方法的重写saveChanges
。
通过脚手架自动生成的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
未读取,因为如果我将数据注释直接放入Users.cs
文件,方法saveChanges()
将引发异常。
我确实找到了此解决方案-> https://stackoverflow.com/a/30127682/6070423 <-,但是它基于AspNet,使用AspNet Core不能使用AssociatedMetadataTypeTypeDescriptionProvider
。
知道我该如何解决吗?
因此,在我在ASP.Net Core论坛上提问后,由于Edward Z的回答,我确实找到了一种使其工作的方法。
基本上,不是创建带有ModelMetadataType的局部类,而是创建了一个Class,其中包含所有需要验证的属性(因此,对于通过脚手架创建的每个类,我都会有一个此类。这样的事情。
// 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;
}
请注意,在第一行中,从实例的类型(即Users)开始,我通过在名称中添加字符串“ Metadata”来检索创建的相应类。然后,我要做的只是创建一个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();
}
这有点棘手,但都可以!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句