新聞中心
本文將討論的是ASP.NET MVC中屬性標(biāo)記的通用擴(kuò)展方法,在這里我們也將更進(jìn)一步的了解ASP.NET MVC的作用。希望大家能用好ASP.MVC。

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的烏什網(wǎng)站設(shè)計(jì)、移動媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
#T#
之前寫過一篇文章《ASP.NET MVC中的驗(yàn)證》,唯一的遺憾就是在使用Data Annotation Validators方式驗(yàn)證的時(shí)候,如果數(shù)據(jù)庫是Entityframework等自動生成的文件,就沒有辦法使用擴(kuò)展屬性標(biāo)記進(jìn)行標(biāo)記。現(xiàn)在已經(jīng)開始有了一些其它的ASP.NET MVC 驗(yàn)證框架,使用上跟Data Annotation Validators差不太多,但是普遍有這樣的問題,如果數(shù)據(jù)庫是Entityframework生成的edm文件,沒有辦法進(jìn)行擴(kuò)展屬性標(biāo)記。
今天在網(wǎng)上發(fā)現(xiàn)了另外一個(gè) ASP.NET MVC 驗(yàn)證框架---xVal框架,使用上跟Data Annotation Validators非常接近,也有類似的問題。
簡單介紹下,xVal是一個(gè)開源的ASP.NET MVC驗(yàn)證框架,有關(guān)它的介紹,可以參考:《xVal - a validation framework for ASP.NET MVC》
xVal使用了MS-PL的開源協(xié)議 ,也就是說,它允許用戶看、修改和分發(fā)源代碼,而不論出自商業(yè)用途還是非商業(yè)用途,類似BSD許可證。
xVal可以通過IRulesProvider接口,通過這個(gè)接口可以進(jìn)行擴(kuò)展,很明顯,它只擴(kuò)展了Castle框架跟NHibernate框架,通過如下兩個(gè)程序集就可以看出來:
xVal.RulesProviders.CastleValidator.dllxVal.RulesProviders.NHibernateValidator.dll基本上可以得出結(jié)論:xVal沒有提供對Entityframework框架的擴(kuò)展,還需要我們做擴(kuò)展。
最終,網(wǎng)上的一片文章給了我提示,問題得到了解決,解決的思路就是建立一個(gè)伙伴類,這個(gè)伙伴類跟原來的類的結(jié)構(gòu)定義是一樣的,在進(jìn)行驗(yàn)證的時(shí)候,不對edm文件中的類進(jìn)行驗(yàn)證,而是對伙伴類進(jìn)行驗(yàn)證。
這里就以xVal框架為例進(jìn)行Demo演示吧。
首先我們建立一個(gè)類模擬Entityframework生成的edm文件中的類,類的定義代碼如下:
模擬EF中的User類
- public partial class User
- {
- public string UserName { get; set; }
- public string Password { get; set; }
- public string Address { get; set; }
- public string Telephone { get; set; }
- public int Age { get; set; }
- public string Email { get;set;}
- }
接下來我們建立一個(gè)伙伴類
伙伴類的代碼
- public class UserMetadata
- {
- [Required]
- [StringLength(10)]
- public string UserName { get; set; }
- [Required]
- [StringLength(18)]
- [DataType(DataType.Password)]
- public string Password { get; set; }
- [Required]
- [StringLength(100)]
- public string Address { get; set; }
- [Required]
- [DataType(DataType.PhoneNumber)]
- public string Telephone { get; set; }
- [Required]
- [Range(1, 100)]
- public int Age { get; set; }
- [Required]
- [DataType(DataType.EmailAddress)]
- public string Email { get; set; }
- }
再接下來,我們使用partial關(guān)鍵字為User類進(jìn)行擴(kuò)展,擴(kuò)展類的定義如下:
擴(kuò)展類的定義
- [MetadataType(typeof(UserMetadata))]
- public partial class User
- {
- }
注意這段代碼:[MetadataType(typeof(UserMetadata))]
為了方便大家閱讀,我把整體代碼貼出來,整體代碼如下:
整體代碼
- using System.ComponentModel.DataAnnotations;
- namespace MVCValidate.Models
- {
- public partial class User
- {
- public string UserName { get; set; }
- public string Password { get; set; }
- public string Address { get; set; }
- public string Telephone { get; set; }
- public int Age { get; set; }
- public string Email { get;set;}
- }
- [MetadataType(typeof(UserMetadata))]
- public partial class User
- {
- }
- public class UserMetadata
- {
- [Required]
- [StringLength(10)]
- public string UserName { get; set; }
- [Required]
- [StringLength(18)]
- [DataType(DataType.Password)]
- public string Password { get; set; }
- [Required]
- [StringLength(100)]
- public string Address { get; set; }
- [Required]
- [DataType(DataType.PhoneNumber)]
- public string Telephone { get; set; }
- [Required]
- [Range(1, 100)]
- public int Age { get; set; }
- [Required]
- [DataType(DataType.EmailAddress)]
- public string Email { get; set; }
- }
- }
接下來,我們要實(shí)現(xiàn)伙伴類跟原類的替換方法了,代碼如下所示:
DataAnnotationsValidationRunner類的代碼
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.ComponentModel.DataAnnotations;
- using System.Linq;
- using xVal.ServerSide;
- namespace MVCValidate.Models
- {
- internal static class DataAnnotationsValidationRunner
- {
- // TODO: DOES NOT SUPPORT METADATA TYPE
- ///// Warning: For some reason, DataTypeAttribute.IsValid() always returns "true", regardless of whether
- ///// it is actually valid. Need to improve this test runner to fix that.
- //public static IEnumerable
GetErrors(object instance) - //{
- // return from prop in TypeDescriptor.GetProperties(instance).Cast
() - // from attribute in prop.Attributes.OfType
() - // where !attribute.IsValid(prop.GetValue(instance))
- // select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
- //}
- ///
- /// Get any errors associated with the model also investigating any rules dictated by attached Metadata buddy classes.
- ///
- ///
- ///
- public static IEnumerable
GetErrors(object instance) - {
- var metadataAttrib = instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true)
- .OfType
().FirstOrDefault(); - var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : instance.GetType();
- var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast
(); - var modelClassProperties = TypeDescriptor.GetProperties(instance.GetType()).Cast
(); - return from buddyProp in buddyClassProperties
- join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
- from attribute in buddyProp.Attributes.OfType
() - where !attribute.IsValid(modelProp.GetValue(instance))
- select new ErrorInfo(buddyProp.Name, attribute.FormatErrorMessage(string.Empty), instance);
- }
- }
- }
完成以上的代碼以后,大部分工作就完成了,接下來,我們在Controller中編寫一個(gè)create方法,來模擬Create操作,代碼如下所示:
Controller層的代碼
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Mvc.Ajax;
- using MVCValidate.Models;
- using xVal.ServerSide;
- namespace MVCValidate.Controllers
- {
- public class UserController : Controller
- {
- [AcceptVerbs(HttpVerbs.Post)]
- public ActionResult Create(User user)
- {
- var errors = DataAnnotationsValidationRunner.GetErrors(user);
- if (errors.Any())
- {
- new RulesException(errors).AddModelStateErrors(ModelState,"user");
- }
- return View();
- }
- }
- }
接下來,編寫View層的代碼,比較簡單,我就直接貼出來了,代碼如下:
View層的代碼
- <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage
" %> - >
- xmlns="http://www.w3.org/1999/xhtml" >
- runat="server">
Create - <%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
- <% using (Html.BeginForm()) {%>
- Fields
for="UserName">UserName: - <%= Html.TextBox("user.UserName") %>
- <%= Html.ValidationMessage("user.UserName")%>
for="Password">Password: - <%= Html.TextBox("user.Password") %>
- <%= Html.ValidationMessage("user.Password")%>
for="Address">Address: - <%= Html.TextBox("user.Address")%>
- <%= Html.ValidationMessage("user.Address")%>
for="Telephone">Telephone: - <%= Html.TextBox("user.Telephone")%>
- <%= Html.ValidationMessage("user.Telephone")%>
for="Age">Age: - <%= Html.TextBox("user.Age")%>
- <%= Html.ValidationMessage("user.Age")%>
for="Email">Email: - <%= Html.TextBox("user.Email")%>
- <%= Html.ValidationMessage("user.Email")%>
- type="submit" value="Create" />
- <% } %>
- <%=Html.ActionLink("Back to List", "Index") %>
最終的效果如下圖所示:
ASP.NET MVC開源驗(yàn)證框架非常的多,只是有相似問題的更多,有了這個(gè)通用的方法,就可以很容易對其他驗(yàn)證框架進(jìn)行擴(kuò)展了。
文章題目:詳解ASP.NET MVC中屬性標(biāo)記的通用擴(kuò)展方法
URL地址:http://www.5511xx.com/article/dhhgiod.html


咨詢
建站咨詢
