model-view-controller – 使用带MVC DataAnnotations和MetaData
发布时间:2020-12-15 08:44:28 所属栏目:Java 来源:网络整理
导读:我正在使用DataAnnotations将验证应用于MVC ViewModel,它是几个实体框架对象和一些自定义逻辑的组合.已经为接口中的实体对象定义了验证,但是如何将此验证应用于ViewModel? 我最初的想法是将接口组合成一个并将组合接口应用于ViewModel,但这不起作用.这是一
我正在使用DataAnnotations将验证应用于MVC ViewModel,它是几个实体框架对象和一些自定义逻辑的组合.已经为接口中的实体对象定义了验证,但是如何将此验证应用于ViewModel?
我最初的想法是将接口组合成一个并将组合接口应用于ViewModel,但这不起作用.这是一些示例代码,展示了我的意思: // interfaces containing DataAnnotations implemented by entity framework classes public interface IPerson { [Required] [Display(Name = "First Name")] string FirstName { get; set; } [Required] [Display(Name = "Last Name")] string LastName { get; set; } [Required] int Age { get; set; } } public interface IAddress { [Required] [Display(Name = "Street")] string Street1 { get; set; } [Display(Name = "")] string Street2 { get; set; } [Required] string City { get; set; } [Required] string State { get; set; } [Required] string Country { get; set; } } // partial entity framework classes to specify interfaces public partial class Person : IPerson {} public partial class Address : IAddress {} // combined interface public interface IPersonViewModel : IPerson,IAddress {} // ViewModel flattening a Person with Address for use in View [MetadataType(typeof(IPersonViewModel))] // <--- This does not work. public class PersonViewModel : IPersonViewModel { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public string Street1 { get; set; } public string Street2 { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } } 我的现实世界问题涉及ViewModel上的大约150个属性,因此它不像样本那样微不足道,重新输入所有属性似乎是对DRY的可怕违反. 有关如何实现这一目标的任何想法? 解决方法
为了使其工作,您需要手动将接口关联为具体类的元数据.
我希望能够添加多个MetadataType属性,但这是不允许的. [AttributeUsage(AttributeTargets.Class,AllowMultiple = false)] // Notice AllowMultiple public sealed class MetadataTypeAttribute : Attribute 因此,这给出了编译错误: [MetadataType(typeof(IPerson))] [MetadataType(typeof(IAddress))] // <--- Duplicate 'MetadataType' attribute public class PersonViewModel : IPersonViewModel 但是,只有一个界面才有效.所以我的解决方案是简单地使用AssociatedMetadataTypeTypeDescriptionProvider关联接口并将其包装在另一个属性中. [AttributeUsage(AttributeTargets.Class,AllowMultiple = true)] public class MetadataTypeBuddyAttribute : Attribute { public MetadataTypeBuddyAttribute(Type modelType,Type buddyType) { TypeDescriptor.AddProviderTransparent( new AssociatedMetadataTypeTypeDescriptionProvider( modelType,buddyType ),modelType); } } 在我的情况下(MVC4),我的接口上的数据注释属性已经起作用.这是因为我的模型直接实现了接口,而不是具有多级继承.但是,在接口级别实现的自定义验证属性不起作用. 只有在手动关联接口时,所有自定义验证才会相应地起作用.如果我理解你的情况,这也是你的问题的解决方案. [MetadataTypeBuddy(typeof(PersonViewModel),typeof(IPerson))] [MetadataTypeBuddy(typeof(PersonViewModel),typeof(IAddress))] public class PersonViewModel : IPersonViewModel (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |