ASP.NET 核心元数据类型属性不工作
ASP.NET Core MetaDataType Attribute not working
我在我的域模型上使用 MetaDataType 属性 class。它应该将属性信息从引用的 class 移动到已设置 MetadataType 属性的 class 中。
但它并不像宣传的那样。是什么导致了这里的问题?
[MetadataType(typeof(ComponentModelMetaData))]
public partial class Component
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Repo> Repos { get; set; }
public string Description { get; set; }
}
public class ComponentModelMetaData
{
[Required(ErrorMessage = "Name is required.")]
[StringLength(30, MinimumLength = 3, ErrorMessage = "Name length should be more than 3 symbols.")]
public string Name { get; set; }
public ICollection<Repo> Repos { get; set; }
[Required(ErrorMessage = "Description is required.")]
public string Description { get; set; }
}
ASP.NET 核心使用
Microsoft.AspNetCore.Mvc **ModelMetadataType**
而不是
System.ComponentModel.DataAnnotations.**MetadataType**
尝试将您的属性更改为 [ModelMetadataType(typeof(ComponentModelMetaData))]
实体class:
namespace CoreProject.Persistence.EFCore
{
public partial class User
{
public User()
{
Reader = new HashSet<Reader>();
Writer = new HashSet<Writer>();
}
public int UserId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string PasswordHashKey { get; set; }
public byte Role { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime CreatedUtc { get; set; }
public DateTime LastUpdateUtc { get; set; }
public byte Status { get; set; }
public bool Deleted { get; set; }
public DateTime? ActivatedUtc { get; set; }
public bool Test { get; set; }
public virtual ICollection<Reader> Reader { get; set; }
public virtual ICollection<Writer> Writer { get; set; }
}
}
元数据(两者必须使用相同的命名空间):
namespace CoreProject.Persistence.EFCore
{
[ModelMetadataType(typeof(IUserMetadata))]
public partial class User : IUserMetadata
{
public string FullName => FirstName + " " + LastName;
}
public interface IUserMetadata
{
[JsonProperty(PropertyName = "Id")]
int UserId { get; set; }
[JsonIgnore]
string Password { get; set; }
[JsonIgnore]
string PasswordHashKey { get; set; }
[JsonIgnore]
byte Role { get; set; }
}
}
另一种方式...使用相同的命名空间
public class ApirolesMetaData
{
[Required]
public string Name { get; set; }
}
[ModelMetadataType(typeof(ApirolesMetaData))]
public partial class Apiroles
{
}
我处于类似的情况,数据库在编码开始之前就存在了。所以 DB 首先似乎是自然而然的选择。生成了 classes,其中 none 有注释。所以添加了 MetadataType
,并找到了这个 Whosebug 页面 - 所以尝试了 ModelMetadataType
。我针对 class 以及接口进行了尝试。
我尝试使用 var validationContext = new ValidationContext(model);
而不是 var editContext = new EditContext(model);
当我使用 var result = Validator.TryValidateObject(model, validationContext, xxxxx, validateAllProperties: true);
时更进一步
当我尝试时我以为我明白了editContext.AddDataAnnotationsValidation();
虽然这适用于带有注释的 class,但它不适用于(对我而言)使用 [MetadataType]
或 [ModelMetadataType]
属性的部分 classes。
我发现(对我而言)唯一可行的解决方法是创建一个新的 class 来包装您要注释的模型。这意味着相同的属性,但 getter 和 setter 指向原始模型。但至少注释会起作用!
public class Model
{
public int ID { get; set; }
public string Name { get; set; }
}
public class AnnotatedModel
{
private readonly Model model;
public AnnotatedModel(Model model)
{
this.model = model;
}
[Range(1, int.MaxValue)]
public int ID { get => model.ID; set => model.ID = value; }
[Required]
[StringLength(maximumLength: 10, ErrorMessage = "Name can't be longer than 10 characters.")]
public string Name { get => model.Name; set => model.Name = value; }
}
所以要使用上面的内容,我需要这样写:
var model = new Model();
var annotatedModel = new AnnotatedModel(model);
var editContext = new EditContext(annotatedModel);
editContext.AddDataAnnotationsValidation();
var result = editContext.Validate();
如果有人能告诉我我缺少什么,太好了!否则我希望这个解决方法对某人有用。
我在我的域模型上使用 MetaDataType 属性 class。它应该将属性信息从引用的 class 移动到已设置 MetadataType 属性的 class 中。 但它并不像宣传的那样。是什么导致了这里的问题?
[MetadataType(typeof(ComponentModelMetaData))]
public partial class Component
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Repo> Repos { get; set; }
public string Description { get; set; }
}
public class ComponentModelMetaData
{
[Required(ErrorMessage = "Name is required.")]
[StringLength(30, MinimumLength = 3, ErrorMessage = "Name length should be more than 3 symbols.")]
public string Name { get; set; }
public ICollection<Repo> Repos { get; set; }
[Required(ErrorMessage = "Description is required.")]
public string Description { get; set; }
}
ASP.NET 核心使用
Microsoft.AspNetCore.Mvc **ModelMetadataType**
而不是
System.ComponentModel.DataAnnotations.**MetadataType**
尝试将您的属性更改为 [ModelMetadataType(typeof(ComponentModelMetaData))]
实体class:
namespace CoreProject.Persistence.EFCore
{
public partial class User
{
public User()
{
Reader = new HashSet<Reader>();
Writer = new HashSet<Writer>();
}
public int UserId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string PasswordHashKey { get; set; }
public byte Role { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime CreatedUtc { get; set; }
public DateTime LastUpdateUtc { get; set; }
public byte Status { get; set; }
public bool Deleted { get; set; }
public DateTime? ActivatedUtc { get; set; }
public bool Test { get; set; }
public virtual ICollection<Reader> Reader { get; set; }
public virtual ICollection<Writer> Writer { get; set; }
}
}
元数据(两者必须使用相同的命名空间):
namespace CoreProject.Persistence.EFCore
{
[ModelMetadataType(typeof(IUserMetadata))]
public partial class User : IUserMetadata
{
public string FullName => FirstName + " " + LastName;
}
public interface IUserMetadata
{
[JsonProperty(PropertyName = "Id")]
int UserId { get; set; }
[JsonIgnore]
string Password { get; set; }
[JsonIgnore]
string PasswordHashKey { get; set; }
[JsonIgnore]
byte Role { get; set; }
}
}
另一种方式...使用相同的命名空间
public class ApirolesMetaData
{
[Required]
public string Name { get; set; }
}
[ModelMetadataType(typeof(ApirolesMetaData))]
public partial class Apiroles
{
}
我处于类似的情况,数据库在编码开始之前就存在了。所以 DB 首先似乎是自然而然的选择。生成了 classes,其中 none 有注释。所以添加了 MetadataType
,并找到了这个 Whosebug 页面 - 所以尝试了 ModelMetadataType
。我针对 class 以及接口进行了尝试。
我尝试使用 var validationContext = new ValidationContext(model);
而不是 var editContext = new EditContext(model);
当我使用 var result = Validator.TryValidateObject(model, validationContext, xxxxx, validateAllProperties: true);
当我尝试时我以为我明白了editContext.AddDataAnnotationsValidation();
虽然这适用于带有注释的 class,但它不适用于(对我而言)使用 [MetadataType]
或 [ModelMetadataType]
属性的部分 classes。
我发现(对我而言)唯一可行的解决方法是创建一个新的 class 来包装您要注释的模型。这意味着相同的属性,但 getter 和 setter 指向原始模型。但至少注释会起作用!
public class Model
{
public int ID { get; set; }
public string Name { get; set; }
}
public class AnnotatedModel
{
private readonly Model model;
public AnnotatedModel(Model model)
{
this.model = model;
}
[Range(1, int.MaxValue)]
public int ID { get => model.ID; set => model.ID = value; }
[Required]
[StringLength(maximumLength: 10, ErrorMessage = "Name can't be longer than 10 characters.")]
public string Name { get => model.Name; set => model.Name = value; }
}
所以要使用上面的内容,我需要这样写:
var model = new Model();
var annotatedModel = new AnnotatedModel(model);
var editContext = new EditContext(annotatedModel);
editContext.AddDataAnnotationsValidation();
var result = editContext.Validate();
如果有人能告诉我我缺少什么,太好了!否则我希望这个解决方法对某人有用。