MVC杂记<二>--Model
在MVC应用程序开发中我们通常手动或者使用Entity FrameWork,Linq to SQL,Nhibernate等ORM技术自动创建对象模型,当然你如果熟悉自动生成代码的工具,就很快会想到这里便会引出一个关于ORM框架提供的部分类功能,具体怎么回事,估计也是很多刚接触MVC的同学遇到后要解决的。
假设我们有这么一个需求就是前端使用ajax验证数据和合法性,而且我们很想偷懒,于是我们想到了System.ComponentModel.DataAnnotations命名空间下的一些特性
好了,我们手动创建一个对象而且对于其中的一些属性使用了DataAnnotations命名空间下的一些特性进行限制
public class Article { public string ArticleId { get; set; } [Required(ErrorMessage = "必须填写文章标题")] public string Title { get; set; } public int ArcitleItemId { get; set; } [MaxLength(200, ErrorMessage = "文字太长啦"), MinLength(10, ErrorMessage = "文字太短了")] public string Content { get; set; } [RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "邮箱不合法")] public string Mail { get; set; } }
但是我们现在用了Entity FrameWork或者是LinQ to SQL 生成的模型,那么我们是不是要在自动生成的对象模型中去改呢?
于是这里就提出了分部类的概念,假设前面自动生成了Article表的实体模型,那么我们怎么去给他的一些属性附加DataAnnotations命名空间下的一些特性进行限制呢,
很快,我们想到了分部类(大家知道意思就行了,这里的分部类什么的有些书上也说是部分类,反正感觉中国文字怎么说大家都懂得,母语博大精深)
public partial class Article
但是问题还是存在怎么去给相应的属性进行限制呢?
看看下面这样可以不?
public partial class Article { public string ArticleId { get; set; } //明显这里会报错!!!!!
原因是,ArticleId已经在EF的DBContent中定义过了,当然这个归根还是属于部分类的使用限制
那么怎么办?.NET考虑到这种情况,于是DataAnnotations命名空间提供了MeteDataType来克服这个关联的限制,使我们可以在部分类中编写和数据模型中相同的属性代码
先提一下MeteData(元数据),它是用来定义数据模型的相关属性。现在我们先看一下代码:
[MetadataType(typeof(ArticleMetaData))] public partial class Article { private class ArticleMetaData { public string ArticleId { get; set; } [Required(ErrorMessage = "必须填写文章标题")] public string Title { get; set; } public int ArcitleItemId { get; set; } [MaxLength(200, ErrorMessage = "文字太长啦"), MinLength(10, ErrorMessage = "文字太短了")] public string Content { get; set; } [RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "邮箱不合法")] public string Mail { get; set; } } }
这里的[MetadataType(typeof(ArticleMetaData))]用于获取与数据模型分部类关联的元数据类并返回元数据类的类型值,以便用来定义数据模型的相关属性, typeof(ArticleMetaData)指定要引用的的元数据类,而这里的ArticleMetaData类的名字并不重要,只是为了定义与数据模型分部类相同的属性值。
这里的 ArticleMetaData类,可以与Article类是父子类关系也可以是兄弟关系。只要保证ArticleMetaData类在Article的可访问范围内就行。