在我的MVC应用程序中,我在域模型中定义了DataAnnotations。尽管在使用域模型时可以检索DataAnnotations属性作为Display等,但在ViewModel上使用相同的属性并使用此ViewModel时,无法检索它们。我认为再次在ViewModel中定义DataAnnotations似乎并不好。那么,我应该遵循哪种方式?
域名模型:
public class Issue
{
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Project Number")]
public int ProjectID { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Issue Definition")]
public string Description { get; set; }
//... removed for brevity
//Navigation Properties:
public virtual ICollection<FileAttachment> FileAttachments { get; set; }
}
视图模型:
public class IssueViewModel
{
public int ID { get; set; }
public int ProjectID { get; set; }
public string Description { get; set; }
//... removed for brevity
//Navigation Properties:
public virtual ICollection<FileAttachment> FileAttachments { get; set; }
}
答案 0 :(得分:5)
您可以创建一个新的好友类,其中包含有关属性和类的所有元数据。
public partial class IssueMetadata
{
[Required(ErrorMessage = "Required")]
[Display(Name = "Project Number")]
public int ProjectID { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Issue Definition")]
public string Description { get; set; }
}
然后,我们必须通过MetadataType
属性告诉MVC框架关于伙伴类,该属性将伙伴类的类型作为其参数。必须在同一名称空间中定义好友类
也必须是partial
类。
[MetadataType(typeof(IssueMetadata))]
public partial class IssueViewModel
{
//...
public int ProjectID { get; set; }
public string Description { get; set; }
//...
}
[MetadataType(typeof(IssueMetadata))]
public partial class Issue
{
[Key]
public int ID { get; set; }
public int ProjectID { get; set; }
public string Description { get; set; }
//... removed for brevity
//Navigation Properties:
public virtual ICollection<FileAttachment> FileAttachments { get; set; }
}
附加说明:
如果IssueMetadata
和Issue
(或IssueViewModel
)类位于不同的程序集中,那么您可以在运行时将类与其伙伴类关联,如下所示:
public class AssociatedMetadataConfig
{
public static void RegisterMetadatas()
{
RegisterPairOfTypes(typeof(Issue), typeof(IssueMetadata));
RegisterPairOfTypes(typeof(IssueViewModel), typeof(IssueMetadata));
}
private static void RegisterPairOfTypes(Type mainType, Type buddyType)
{
AssociatedMetadataTypeTypeDescriptionProvider typeDescriptionProvider
= new AssociatedMetadataTypeTypeDescriptionProvider(mainType, buddyType);
TypeDescriptor.AddProviderTransparent(typeDescriptionProvider, mainType);
}
}
并且,只需在global.asax
中调用此静态方法:
AssociatedMetadataConfig.RegisterMetadatas();
答案 1 :(得分:0)
@StephenMuecke是对的。 DomainModel属性和ViewModel属性不同,您可以在模型中单独使用它们。但如果我是你,我会在这种情况下使用。您可以为ViewModel创建Partial类,并从此ViewModel类继承您的DomainModel。
像:
public class IssueVM
{
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Project Number")]
public int ProjectID { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Issue Definition")]
public string Description { get; set; }
//... removed for brevity
//Navigation Properties:
public virtual ICollection<FileAttachment> FileAttachments { get; set; }
}
public class IssueDM : IssueVM
{
// Other Fields
}
这样你就有了一个基类ViewModel(少了字段)和一个更大的类,有更多的字段用于数据库操作。您的ViewModel数据注释属性也以这种方式在DomainClass中继承。
我并不认为这是最好的方式,但我使用它并且工作正常。