Linq to SQL 加注Data Annotation在 Asp.Net MVC2中的应用


一.写作前提 

  最近正在做一个Asp.Net MVC2的Project,用到了Linq to SQL,但是对于如何在MVC2中使用 Linq to SQL 生成的强类型加注Data Annotation,我们都知道在MVC2中我们可以定义自己的Model,然后给Model加Data Annotation,从而在View中可以实现完美的Client Validation(这些Data Annotation也我们也可以去自己定义)。但是对于Linq to SQL 生成的强类型,我们有两个问题,第一,应该如何实现它的Data Annotation;第二,当我们的Database结构发生改变时,我们通常需要把Linq to SQL里相应的对象先删除,然后再重新映射,这时我们如何保证我们加的Data Annotation只需要进行最小的改动就可以完成对新映射的支持?

  下面我们就上面的问题进行分析和提出我们的解决方案。

  二.通常MVC的做法               

  首先我们来做一个比较,自定义Model加Annotation,如表1所示:

  图表1:Product Class 的定义

 1 public class Product
 2 {
 3   [DisplayName("Product Name")]
 4   [Required(ErrorMessage="Product Name is Required.")]
 5   [StringLength(50,ErrorMessage="Max Length of Product Name can not greater than 50 characters.")]
 6     public string Name
 7     {
 8       get;
 9       set;
10     }
11 
12   [DisplayName("Product Type")]
13   [Required(ErrorMessage = "Product Type is Required.")]
14   [StringLength(20, ErrorMessage = "Max Length of Product Name can not greater than 20 characters.")]
15   public string Type
16   {
17     get;
18     set;
19   }
20 }
Controller 定义如图表2所示:

  图表2:Product Controller的使用

 1 public class ProductController : Controller
 2 {
 3   public ActionResult CreateProduct()
 4   {
 5     this.ViewData.Model = new Product();
 6     return View();
 7   }
 8 
 9   [HttpPost]
10   public ActionResult CreateProduct(Product p)
11   {
12     if (this.ModelState.IsValid)
13     {
14       //Save Data
15     }
16     else
17     {
18       this.ViewData.Model = p;
19     }
20     return View();
21   }
22 }

  在Site.Master中加入如图表3所示:

  图表3:Enable Client Validation

1 <script type="text/javascript" src="<%=Url.Content("~/Scripts/MicrosoftAjax.js") %>" ></script>
2 
3 <script type="text/javascript" src="<%=Url.Content("~/Scripts/MicrosoftMvcValidation.js") %>" ></script> <% Html.EnableClientValidation(); %>

  View代码如图表4所示:

  图表4:View中对Product的应用

 1 <%using (Html.BeginForm())
 2  { %>
 3 <p>
 4   <%=Html.LabelFor(Model => Model.Name)%>
 5   <%=Html.TextBoxFor(Model => Model.Name)%>
 6   <%=Html.ValidationMessageFor(Model => Model.Name)%>
 7 </p>
 8 <p>
 9   <%=Html.LabelFor(Model => Model.Type)%>
10   <%=Html.TextBoxFor(Model => Model.Type)%>
11   <%=Html.ValidationMessageFor(Model => Model.Type)%>
12 </p>
13 <input type="submit" value="Submit" />
14 <%} %>

  上面我们定义了Model Product,定义了两具属性,分别是Name和Type,并且给他们加了Annotation(注意:DisplayName是 System.ComponentModel命名空间下面的),Asp.net MVC2在做Validation的时候,他会根据我们所加注的这些Annotation对对应的Property进行验证。然后我们在 Site.Master指定他们进行Client端验证,在Create Product 的View中我们加以应用,当我们点Submit的时候,它并没有做Postback,并且帮我们做了所需求的 Validation,如图表5所示,这使得我们MVC的开发更方便、更简洁,同时也带了更好的视觉效果。

  图表5:View调用的结果

  三.Linq to SQL 在MVC2的问题与本文解决方案                   

  Ok,上面是我们传统的做法,但是在我们的项目中使用的是Linq to SQL,之所以使用Linq to SQL,是因为我们只需要把Database中的Table、 Stored Procedure或者Function等拖到我们的Linq to SQL文件中,他就会帮我们生成对应的强类型文件,方便我们的使用,特别是在Asp.Net  MVC中的使用。 但是我们如何给Linq to SQL生成的类类型加Data Annotation呢?

  首先我们可以简单的想,直接在Linq to SQL 生成的cs文件中引用System.ComponentModel.DataAnnotations,然后在对应的Property中加我们所需要的 Annotatio,从理想的状态来讲,我们说这个方案是可行的,但是前提条件是你所设计的Table、Stored Procedure或者Function 结构不会再更改,因为当我们Linq to SQL里的对象在Database的结构发生变化时,我们需要删除Linq to SQL文件中的对象,然后从Database重新的拖入,以生成更新后的强类型文件,那么我们之前加入的Annotation也会被删除掉,后果就是我们需要重新加注Data Annotation,这样会增加我们很大的工作量, 那么我们如何来解决这样的问题呢?

在Linq to SQL中,如果你的Database的表的名称是T_PRODUCT,那么当你把表插入到Linq to SQL的文件中生,他会帮我们生成对应名称为T_PRODUT的Class。如图表6所示:

  图表6:Database Table在Linq to SQL中显示

  我们的解决方案是定义一个新的Class(我们这里叫ProductAnnotation),然后在里面加入哪些需要加注Annotation的Properties(Property的名字需要和T_PRODUCT表中的字段相同),如图表7所示:

  图表7:为T_PRODUCT表定义Data Annotation

 1 public class ProductAnnotation
 2 {
 3   [DisplayName("Product Name")]
 4   [Required(ErrorMessage = "Product Name is Required.")]
 5   [StringLength(50, ErrorMessage = "Max Length of Product Name can not greater than 50 characters.")]
 6   public string Name { get; set; }
 7 
 8   [DisplayName("Product Type")]
 9   [Required(ErrorMessage = "Product Type is Required.")]
10   [StringLength(20, ErrorMessage = "Max Length of Product Name can not greater than 20 characters.")]
11 
12   public string Type { get; set; }
13 }

  可以看出,这和我们之前定义的那Product没有多大差别,关键在于这里面只需要加入那些我们需要的字段,例如表里的Oid我们不需要,那么就没有必要放进来,这使用我们的设计更加自由。上面我们定义完了所需要的Annotation,也解决了本文开始的第一个问题。下面我们需要做的事情就是把定义的这个包含Annotation的Class和我们的T_PRODUCT表进行绑定,方法如图表8所示:

  图表8:联合(绑定)Data Annotation到Linq to SQL中T_PRODUCT Class

1 [MetadataType(typeof(ProductAnnotation))]
2 public partial class T_PRODUCT
3 { 
4     
5 }

  上面 partial的意思就是对T_PRODUCT表进行部分定义,关键在于在它的上面有一个MetadataType的 Atrribute,并且里面所引用的正是我们上面所定义的Class,System.ComponentModel.DataAnnotations命名空间下的MetadataType Attribute的作用就是将两个进行整合,但是Asp.Net MVC 去读那些Validation的时候,他就会去从我们定义的ProductAnnotation中对应的字段去读取。

  假设我们把Database中T_PRODUCT表中的Name改成了ProductName,我们需要把Linq to SQL的中对应的表重新拖入,生成新的强类型Class,到我们的ProductAnnotation Class中修改相应的名称即可,而无须重新加注所有字段了,其它修改类似,这也就解决了本文的问题。

  以上就是我们的解决方案,他实现的效果和我们上面所实现 的效果是一样的。

  四.总结                          

  通过对Asp.Net MVC2  Data Annotation的分析,介绍了如何通过实现对Linq to SQL加注Data Annotation。通过上面的分析主要了解了如下内容:

  Asp.Net MVC2中利用Data Annotation定义Validation的使用。

  实现对Linq to SQL生成的强类型Class加Validation的方法


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3