dho*_*hee 3 model-view-controller data-annotations
我正在使用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; }
}
Run Code Online (Sandbox Code Playgroud)
我的现实世界问题涉及ViewModel上的大约150个属性,因此它不像样本那样微不足道,重新输入所有属性似乎是对DRY的可怕违反.
有关如何实现这一目标的任何想法?
为了使其工作,您需要手动将接口关联为具体类的元数据.
我希望能够添加多个MetadataType属性,但这是不允许的.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] // Notice AllowMultiple
public sealed class MetadataTypeAttribute : Attribute
Run Code Online (Sandbox Code Playgroud)
因此,这给出了编译错误:
[MetadataType(typeof(IPerson))]
[MetadataType(typeof(IAddress))] // <--- Duplicate 'MetadataType' attribute
public class PersonViewModel : IPersonViewModel
Run Code Online (Sandbox Code Playgroud)
但是,只有一个界面才有效.所以我的解决方案是简单地使用AssociatedMetadataTypeTypeDescriptionProvider关联接口并将其包装在另一个属性中.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class MetadataTypeBuddyAttribute : Attribute
{
public MetadataTypeBuddyAttribute(Type modelType, Type buddyType)
{
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(
modelType,
buddyType
),
modelType);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下(MVC4),我的接口上的数据注释属性已经起作用.这是因为我的模型直接实现了接口,而不是具有多级继承.但是,在接口级别实现的自定义验证属性不起作用.
只有在手动关联接口时,所有自定义验证才会相应地起作用.如果我理解你的情况,这也是你的问题的解决方案.
[MetadataTypeBuddy(typeof(PersonViewModel), typeof(IPerson))]
[MetadataTypeBuddy(typeof(PersonViewModel), typeof(IAddress))]
public class PersonViewModel : IPersonViewModel
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1412 次 |
| 最近记录: |