




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
ASP.NETMVC實(shí)訓(xùn)教程機(jī)械工業(yè)出版社趙魯濤李曄等編目錄模型層概述與執(zhí)行機(jī)制實(shí)體數(shù)據(jù)模型2.12.22.3LINQ語(yǔ)句與使用2.4模型的數(shù)據(jù)校驗(yàn)第二章模型第二章模型2.1模型層概述與執(zhí)行機(jī)制模型(Model)層是MVC4框架的最底層部分,它的職能主要有兩個(gè):①提供數(shù)據(jù)庫(kù)的支持,包括對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增加(insert)、刪除(delete)、修改(update)和查找(select)等具體操作;②提供軟件模型、應(yīng)用的具體實(shí)現(xiàn)過(guò)程,也就是最底層的方法的具體內(nèi)容,封裝給上層接口進(jìn)行調(diào)用。在MVC框架中,模型層的執(zhí)行機(jī)制如圖2.1所示。圖2.1模型層在MVC框架中的執(zhí)行機(jī)制第二章模型2.1模型層概述與執(zhí)行機(jī)制ASP.NET的MVC4框架中,模型表示應(yīng)用程序的數(shù)據(jù)對(duì)象,以及相應(yīng)的業(yè)務(wù)領(lǐng)域邏輯,包括數(shù)據(jù)驗(yàn)證和業(yè)務(wù)規(guī)則等內(nèi)容。因此,模型是ASP.NETMVC4框架的核心部分。由于模型層應(yīng)該只和數(shù)據(jù)及業(yè)務(wù)邏輯有關(guān),也就是說(shuō),其不應(yīng)該負(fù)責(zé)處理所有與數(shù)據(jù)或業(yè)務(wù)處理無(wú)關(guān)的操作,如不應(yīng)該控制網(wǎng)站的執(zhí)行流程等,因此,模型層應(yīng)該只專注于如何有效地提供數(shù)據(jù)訪問(wèn)機(jī)制、交互環(huán)境、數(shù)據(jù)格式驗(yàn)證、業(yè)務(wù)邏輯驗(yàn)證等服務(wù)。同時(shí),由于模型的獨(dú)立性非常高,因此,如果一個(gè)VisualStudio方案中有多個(gè)要開(kāi)發(fā)的項(xiàng)目,應(yīng)該將模型獨(dú)立成一個(gè)項(xiàng)目,好讓此模型項(xiàng)目能在不同的項(xiàng)目之間共享使用。第二章模型2.2實(shí)體數(shù)據(jù)模型MVC4中,實(shí)體數(shù)據(jù)類型是系統(tǒng)與數(shù)據(jù)庫(kù)的交互接口,非常重要。不同于Java使用JDBC-ODBC的數(shù)據(jù)庫(kù)連接方式,MVC4在數(shù)據(jù)庫(kù)連接的基礎(chǔ)之上,將數(shù)據(jù)庫(kù)在系統(tǒng)中抽象成為一個(gè)具體的數(shù)據(jù)庫(kù)實(shí)體對(duì)象,在實(shí)體對(duì)象中映射出數(shù)據(jù)庫(kù)中的各個(gè)表、各個(gè)字段的具體內(nèi)容,完全模擬數(shù)據(jù)庫(kù)。也就是說(shuō),在編寫(xiě)的工程中,直接在系統(tǒng)中就可以查到各個(gè)數(shù)據(jù)表的組成、樣式和取值等,不用再去數(shù)據(jù)庫(kù)中進(jìn)行查找。建立數(shù)據(jù)庫(kù)實(shí)體的方法如例2.1所示?!纠?.1】數(shù)據(jù)庫(kù)實(shí)體的建立。本例是對(duì)數(shù)據(jù)庫(kù)實(shí)體建立步驟的具體說(shuō)明。通過(guò)本例,讀者可以完全掌握實(shí)體數(shù)據(jù)庫(kù)建立的方法與機(jī)制。首先,數(shù)據(jù)庫(kù)名稱為MyStudent,數(shù)據(jù)庫(kù)具體結(jié)構(gòu)見(jiàn)表2.1~表2.3。序號(hào)字段字段描述格式長(zhǎng)度是否主碼備注1Sno學(xué)號(hào)nVarchar5是
2Sname姓名nVarchar8
3Ssex性別nVarchar2
4Sage年齡Numeric
5Sdept所在系所nVarchar20
表2.1
Student(學(xué)生)表第二章模型2.2實(shí)體數(shù)據(jù)模型表2.3SC(選課)表序號(hào)字段字段描述格式長(zhǎng)度是否主碼備注1Cno課程號(hào)nVarchar5是
2Cname課程名稱nVarchar20
3Cpno先行課號(hào)nVarchar5
外碼4Ccredit學(xué)分Numeric
表2.2Couarse(課程)表序號(hào)字段字段描述格式長(zhǎng)度是否主碼備注1Sno學(xué)號(hào)nVarchar5
2Cno課程號(hào)nVarchar5
3Grade成績(jī)Numeric
第二章模型2.2實(shí)體數(shù)據(jù)模型表2.4Student表初始值數(shù)據(jù)庫(kù)的初始賦值見(jiàn)表2.4~表2.6。SnoSnameSsexSageSdept95001李名男20CS95002張明女19IS95003劉紅女19MA95004陳列男19ISCnoCnameCpnoCcredit1數(shù)據(jù)庫(kù)542數(shù)學(xué)
23信息系統(tǒng)144操作系統(tǒng)635數(shù)據(jù)結(jié)構(gòu)746數(shù)據(jù)處理
27PASCAL語(yǔ)言64表2.5Course表初始值第二章模型2.2實(shí)體數(shù)據(jù)模型表2.6SC表初始值SnoCnoGrade9500119795001290950013809500228695002392具體數(shù)據(jù)實(shí)體的建立過(guò)程見(jiàn)1.4.2節(jié)Step01~Step05。建立好的數(shù)據(jù)庫(kù)實(shí)體如圖2.2所示。圖2.2
MyStudent數(shù)據(jù)庫(kù)實(shí)體圖第二章模型2.2實(shí)體數(shù)據(jù)模型需要注意的是,在Step05中勾選“確定所生成對(duì)象名稱的單復(fù)數(shù)形式”復(fù)選框后,系統(tǒng)會(huì)將每個(gè)表以一個(gè)集合的復(fù)數(shù)形式給出,而每一個(gè)個(gè)體元素則以一個(gè)單一個(gè)體(單數(shù))形式給出。也就是說(shuō),在創(chuàng)建實(shí)體數(shù)據(jù)類型時(shí),實(shí)體數(shù)據(jù)類型是有單復(fù)數(shù)之分的,數(shù)據(jù)庫(kù)和表的類型使用復(fù)數(shù),實(shí)例使用單數(shù),因此需要注意有無(wú)s的區(qū)分。在數(shù)據(jù)實(shí)體中,右擊實(shí)體表,在彈出的快捷菜單中選擇“屬性”,會(huì)在UI界面的右下方顯示數(shù)據(jù)表的屬性。通過(guò)屬性,可以進(jìn)行表名稱、表對(duì)應(yīng)集的修改,單擊每一個(gè)表內(nèi)容,如Student表的Sno屬性,會(huì)在右下角顯示Sno屬性的相關(guān)屬性。我們可以在這里進(jìn)行表與屬性的修改?!纠?.2】對(duì)表字段進(jìn)行操作。1)選擇“Student”表,將表名稱改為“PersonInSchool”,對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的“Student”表。2)選擇“Student”表中的“Sname”字段,修改其最大長(zhǎng)度為6,名稱為“StudentName”,對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的“Sname”屬性,默認(rèn)值設(shè)為“省略”;設(shè)置“Sage”的名稱為“StudentAge”,對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的“Sage”屬性,設(shè)置默認(rèn)值為“18”。3)針對(duì)以上要求,在1.4.2節(jié)的例子中進(jìn)行修改,完成以上內(nèi)容,并保證系統(tǒng)的正確運(yùn)行。以上內(nèi)容均在右側(cè)屬性欄中進(jìn)行修改即可。需要注意的是,當(dāng)完成以上修改后,程序中之前應(yīng)用的字段都要進(jìn)行相應(yīng)的對(duì)照修改,這樣才能保證系統(tǒng)的正常運(yùn)行。第二章模型2.3LINQ語(yǔ)句與使用在MVC4的數(shù)據(jù)部分,我們將不再使用普通的SQL語(yǔ)句作為數(shù)據(jù)庫(kù)操作語(yǔ)言,而是使用語(yǔ)言集成查詢(LanguageIntegratedQuery,LINQ)作為固定數(shù)據(jù)庫(kù)的操作語(yǔ)言。LINQ是ASP.NET中的新特性,它分為L(zhǎng)INQtoObject、LINQtoSQL、LINQtoXML、LINQtoDataSet,并且它提供了統(tǒng)一的語(yǔ)法來(lái)查詢多種異構(gòu)數(shù)據(jù)源,開(kāi)發(fā)人員可使用任何.NET語(yǔ)言(比如C#或者VB.NET)來(lái)查詢數(shù)據(jù)源中的數(shù)據(jù),而不用處理各種異構(gòu)數(shù)據(jù)源之間的差異。LINQ允許開(kāi)發(fā)人員查詢?nèi)魏螌?shí)現(xiàn)了IEnumerable<>接口的集合,如Array、List、XML、DOM或者SQLServer數(shù)據(jù)表。LINQ提供了翻譯時(shí)的類型安全檢查和動(dòng)態(tài)類型組合等功能,這里重點(diǎn)講解如何使用LINQtoSQL訪問(wèn)數(shù)據(jù)庫(kù)。第二章模型2.3LINQ語(yǔ)句與使用LINQ與SQL相比,有不少的好處,特別是學(xué)過(guò)SQL的人員更容易上手。LINQ的優(yōu)點(diǎn)主要表現(xiàn)在:1)無(wú)須復(fù)雜的學(xué)習(xí)過(guò)程即可上手。2)編寫(xiě)更少代碼即可創(chuàng)建完整的應(yīng)用。3)更快開(kāi)發(fā)錯(cuò)誤更少的應(yīng)用。4)無(wú)須利用“奇怪”的編程技巧就可合并數(shù)據(jù)源。5)提高新開(kāi)發(fā)者的開(kāi)發(fā)效率。6)任何對(duì)象或數(shù)據(jù)源都可以定制實(shí)現(xiàn)LINQ適配器,為數(shù)據(jù)交互帶來(lái)真正的便利。2.3.1使用LINQ的好處第二章模型2.3LINQ語(yǔ)句與使用1.DataContext類型介紹DataContext類型(數(shù)據(jù)上下文)是System.Data.Linq命名空間下的重要類型,用于把查詢語(yǔ)句翻譯成SQL語(yǔ)句,以及把數(shù)據(jù)從數(shù)據(jù)庫(kù)返回給調(diào)用方和把實(shí)體的修改寫(xiě)入數(shù)據(jù)庫(kù)。DataContext提供了以下一些實(shí)用的功能:1)以日志形式記錄DataContext生成的SQL。2)執(zhí)行SQL(包括查詢和更新語(yǔ)句)。3)創(chuàng)建和刪除數(shù)據(jù)庫(kù)。DataContext是實(shí)體和數(shù)據(jù)庫(kù)之間的橋梁,首先我們需要定義映射到數(shù)據(jù)表的實(shí)體。Step01:定義實(shí)體類。2.3.2LINQtoSQL的預(yù)備知識(shí)第二章模型2.3LINQ語(yǔ)句與使用以MyStudent數(shù)據(jù)庫(kù)為例,上述Student類被映射成一個(gè)表,對(duì)應(yīng)數(shù)據(jù)庫(kù)中的Student表。然后,在類型中定義了4個(gè)屬性,對(duì)應(yīng)表中的4個(gè)字段。其中,Sname字段是主碼,如果沒(méi)有指定Column特性的Name屬性,那么系統(tǒng)會(huì)把屬性名作為數(shù)據(jù)表的字段名,也就是說(shuō),實(shí)體類的屬性名就需要和數(shù)據(jù)表中的字段名一致。Step02:現(xiàn)在,創(chuàng)建一個(gè)ASP.NET頁(yè)面,然后在頁(yè)面上加入一個(gè)GridView控件數(shù)據(jù)綁定。Step03:使用DataContext類型把實(shí)體類和數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行關(guān)聯(lián)。用戶可以直接在DataContext構(gòu)造方法中定義連接字符串,也可以使用IDbConnection。usingSystem.Data.SqlClient;IDbConnectionconn=newSqlConnection("server=xxx;database=Northwind;uid=xxx;pwd=xxx");DataContextctx=newDataContext(conn);Step04:然后,通過(guò)GetTable獲取表示底層數(shù)據(jù)表的Table類型,顯然,數(shù)據(jù)庫(kù)中的Student表的實(shí)體是Student類型。隨后的查詢語(yǔ)句,即使用戶不懂SQL應(yīng)該也能看明白。從Student表中找出Sname以“李”開(kāi)頭的記錄,并把Sname、Ssex、Sage及Sdept封裝成新的匿名類型進(jìn)行返回。2.3.2LINQtoSQL的預(yù)備知識(shí)第二章模型2.3LINQ語(yǔ)句與使用結(jié)果如圖2.3所示。2.3.2LINQtoSQL的預(yù)備知識(shí)圖2.3運(yùn)行結(jié)果2.匿名類型在動(dòng)態(tài)語(yǔ)言中,用戶可能比較熟悉的概念是匿名類型(anonymoustype)。當(dāng)需要?jiǎng)?chuàng)建臨時(shí)類型,卻并不想創(chuàng)建類時(shí),可以使用匿名類型。下面的代碼演示了如何在C#中創(chuàng)建匿名類型。varstudent=new{FirstName="Stephen",LastName="Walt"};注意:student變量并沒(méi)有指定類型(JavaScript或VBScript與之非常類似)。盡管如此,student仍然具有它的類型,只是用戶不知道它的名字而已,它是匿名的,理解這一點(diǎn)非常重要。僅僅一行代碼,我們即創(chuàng)建了一個(gè)新的類,又初始化了它的屬性,十分簡(jiǎn)潔。在使用LINQtoSQL時(shí),匿名類型非常有用,因?yàn)橛脩魰?huì)發(fā)現(xiàn)經(jīng)常需要?jiǎng)?chuàng)建一些臨時(shí)功能的新類型。例如,當(dāng)執(zhí)行一個(gè)查詢時(shí),也許希望返回一個(gè)類,用來(lái)代表一些數(shù)據(jù)庫(kù)列的集合,此時(shí)將需要?jiǎng)?chuàng)建一個(gè)代表這些列的臨時(shí)類。第二章模型2.3LINQ語(yǔ)句與使用2.3.2LINQtoSQL的預(yù)備知識(shí)3.Lambda表達(dá)式在上述這段代碼中,添加了C#4.0的新語(yǔ)法:s=>(s.IndexOf("a")>-1),這就是一個(gè)Lambda表達(dá)式,現(xiàn)在只需要簡(jiǎn)單的一些字符就完成了原本需要單獨(dú)創(chuàng)建一個(gè)方法的過(guò)程,而且語(yǔ)法相當(dāng)簡(jiǎn)潔。通過(guò)上面的例子,我們現(xiàn)在對(duì)Lambda表達(dá)式已經(jīng)有了一個(gè)基本的了解。一個(gè)Lambda表達(dá)式通常由如下部分組成。1)首先是一個(gè)參數(shù)或者參數(shù)列表,也就是輸入變量。在上述示例中,由于需要為委托傳遞一個(gè)字符串類型的變量,因此左側(cè)的是s變量。2)接著是=>符號(hào),稱為L(zhǎng)ambda運(yùn)算符,MSDN中將這個(gè)符號(hào)讀作“goesto”。3)最后是Lambda語(yǔ)句(塊),可以是單條語(yǔ)句也可以是多個(gè)語(yǔ)句的語(yǔ)句塊。為了加深印象,讀者可以這樣來(lái)理解Lambda表達(dá)式:要處理的參數(shù)=>處理這些參數(shù)的語(yǔ)句(塊)說(shuō)明如下:①要處理的參數(shù):可以有一個(gè)參數(shù)、多個(gè)參數(shù),或者無(wú)參數(shù)。②處理這些參數(shù)的語(yǔ)句(塊):這部分就是我們平時(shí)編寫(xiě)函數(shù)時(shí)的實(shí)現(xiàn)部分(函數(shù)體)。第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢使用LINQtoSQL進(jìn)行查詢,類似于創(chuàng)建一個(gè)反向的SQL查詢。LINQtoSQL查詢以一個(gè)from子句開(kāi)始,它指定了數(shù)據(jù)的位置,然后,指定where子句過(guò)濾數(shù)據(jù),最后,指定用來(lái)表示數(shù)據(jù)的select子句(決定要返回的對(duì)象和屬性)。因此,下列查詢:將被C#編譯器翻譯成下面的查詢:varq=db.Customers.Where(c=>c.City=="London").Select(c=>c);第一個(gè)查詢使用了查詢語(yǔ)法,第二個(gè)查詢使用了方法語(yǔ)法。這兩種查詢是相同的。注意:使用方法語(yǔ)法的查詢?cè)赪here()和Select()方法中允許使用Lambda表達(dá)式。Where()方法中的Lambda表達(dá)式用來(lái)過(guò)濾數(shù)據(jù),Select()方法指明要返回的對(duì)象合適屬性。第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢1.簡(jiǎn)單查詢【例2.3】篩選年齡為20的學(xué)生。2.條件查詢【例2.4】使用SELECT和條件語(yǔ)句返回學(xué)生姓名和所在系所的序列,其中系所只能是CS。第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢【例2.5】使用嵌套查詢返回所有選課人的學(xué)號(hào)、姓名、課程號(hào)、課程名稱、先行課號(hào)、學(xué)分和成績(jī)。【例2.6】使用Count/Sum/Min/Max/Avg操作符進(jìn)行查詢。1)查找最小年齡。varq=db.Studnets.Select(p=>p.Sage).Min();2)查找擁有最低學(xué)分的課程。varq=db.Course.Min(o=>o.Ccredit);第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢【例2.7】使用OrderBy按課程學(xué)分對(duì)課程進(jìn)行排序?!纠?.8】使用GroupBy進(jìn)行查詢。使用OrderBy、Max和GroupBy得到每個(gè)學(xué)生的最高成績(jī),并按Sno對(duì)其進(jìn)行排序。第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢3.模糊查詢使用LINQtoSQL進(jìn)行模糊查詢,可以有很多方法,如Length、Substring、Contain、StartsWith、IndexOf等?!纠?.9】下面查詢并返回以“李”開(kāi)頭的全部學(xué)生信息。MyStudentsContextdb=newMyStudentsDataContext();varq=db.Students.where(m=>m.Sname.StartsWith("李"))4.多表查詢【例2.10】在select子句中使用外碼來(lái)篩選成學(xué)生和成績(jī)。像上程序2、3行所示,語(yǔ)句沒(méi)有join和into,則被翻譯成SelectMany;同時(shí)有join和in時(shí),那么語(yǔ)句就被翻譯為GroupJoin。在這里,in的概念是對(duì)其結(jié)果進(jìn)行重新命名。第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢【例2.11】顯式聯(lián)接兩個(gè)表并從這兩個(gè)表投影出結(jié)果?!纠?.12】顯式聯(lián)接三個(gè)表并分別從每個(gè)表投影出結(jié)果。第二章模型2.3LINQ語(yǔ)句與使用2.3.3LINQtoSQL的查詢【例2.13】以Students作為主表,SCs作為要連接的表,當(dāng)SCs表中內(nèi)容為空時(shí),用null值填充。join的結(jié)果重命名為ords,使用DefaultIfEmpty()函數(shù)對(duì)其再次查詢。其最后的結(jié)果中有個(gè)Order,因?yàn)椤癴romoinords.DefaultIfEmpty()”是對(duì)ords組再一次遍歷,所以,最后結(jié)果中的Order并不是一個(gè)集合。但是,如果沒(méi)有“fromoinords.DefaultIfEmpty()”這條語(yǔ)句,而且最后的select語(yǔ)句寫(xiě)成“selectnew{e.Sname,Order=ords}”的話,那么Order就是一個(gè)集合。第二章模型2.3LINQ語(yǔ)句與使用2.3.4LINQtoSQL進(jìn)行插入插入記錄時(shí)需要先創(chuàng)建一條新記錄(對(duì)象),包括數(shù)據(jù)表中不能為null的所有字段,然后將這個(gè)對(duì)象作為屬性成員添加到原有的類中,最后增加到數(shù)據(jù)庫(kù)中。使用LINQtoSQL添加或插入新記錄也是這樣的步驟。首先,需要使用InsertOnSubmit()方法將一個(gè)實(shí)體添加到一個(gè)已經(jīng)存在的表中。然后,調(diào)用DataContext中的SubmitChanges()對(duì)數(shù)據(jù)庫(kù)執(zhí)行SQLINSERT語(yǔ)句。實(shí)例代碼:第二章模型2.3LINQ語(yǔ)句與使用2.3.5LINQtoSQL進(jìn)行更新使用LINQtoSQL進(jìn)行更新時(shí),可以通過(guò)修改實(shí)體屬性并調(diào)用DataContext的SubmitChanges()方法來(lái)對(duì)LINQtoSQL實(shí)體和底層的數(shù)據(jù)庫(kù)表進(jìn)行更新。實(shí)例代碼:總結(jié)一下,這段代碼就是先得到產(chǎn)品ID=12的產(chǎn)品,然后修改產(chǎn)品的單價(jià)屬性,最后調(diào)用SubmitChanges()方法向數(shù)據(jù)庫(kù)提交修改。第二章模型2.3LINQ語(yǔ)句與使用2.3.6LINQtoSQL進(jìn)行刪除使用LINQtoSQL進(jìn)行刪除時(shí),可以采用下面的代碼。實(shí)例代碼:該段代碼一開(kāi)始從Student數(shù)據(jù)表中獲取m.Sno==int.Parse(TextBox8.Text)的記錄,然后用DeleteOnSubmit()的方法將該條記錄刪除,最后調(diào)用SubmitChanges()方法向數(shù)據(jù)庫(kù)提交修改。第二章模型2.4模型的數(shù)據(jù)校驗(yàn)對(duì)用戶輸入的驗(yàn)證以及強(qiáng)制業(yè)務(wù)規(guī)則/邏輯是大多數(shù)Web應(yīng)用的核心需求。ASP.NETMVC4包含了許多新的特性,明顯簡(jiǎn)化了對(duì)用戶輸入的驗(yàn)證以及在模型/視圖模型中對(duì)驗(yàn)證邏輯的強(qiáng)行實(shí)施。這些特性是這樣設(shè)計(jì)的,驗(yàn)證邏輯在服務(wù)器上執(zhí)行,也可以選擇在客戶端通過(guò)JavaScript來(lái)執(zhí)行。ASP.NETMVC4中的驗(yàn)證設(shè)施和特性這樣設(shè)計(jì),以便:1)開(kāi)發(fā)人員可以輕松地利用內(nèi)置于.NET框架中的DataAnnotation驗(yàn)證支持。DataAnnotation提供了一個(gè)非常簡(jiǎn)便的方式,可以使用最少的代碼在對(duì)象和屬性上用聲明的方式添加驗(yàn)證規(guī)則。2)開(kāi)發(fā)人員可以集成他們自己的驗(yàn)證引擎,或者利用現(xiàn)有的驗(yàn)證框架,如Castle驗(yàn)證器或EntLib驗(yàn)證庫(kù)。ASP.NETMVC4的驗(yàn)證特性是設(shè)計(jì)用來(lái)在利用新的ASP.NETMVC4的驗(yàn)證設(shè)施(包括客戶端驗(yàn)證、模型綁定驗(yàn)證等)的同時(shí),簡(jiǎn)化任何類型的驗(yàn)證架構(gòu)的插入的。這意味著在常見(jiàn)的應(yīng)用場(chǎng)景中啟用驗(yàn)證是極其容易的,同時(shí)對(duì)更高級(jí)的場(chǎng)景還能保持極高的靈活性。第二章模型2.4模型的數(shù)據(jù)校驗(yàn)下面在ASP.NETMVC4中全程演示一個(gè)簡(jiǎn)單的CRUD場(chǎng)景示例,利用新的內(nèi)置DataAnnotation驗(yàn)證支持。具體來(lái)說(shuō),就是實(shí)現(xiàn)一個(gè)“Create”表單來(lái)允許用戶輸入個(gè)人數(shù)據(jù)。我們想要確保在輸入數(shù)據(jù)保存到數(shù)據(jù)庫(kù)之前是合法的,如果不合法,就顯示合適的錯(cuò)誤消息。我們想要使得這個(gè)驗(yàn)證同時(shí)在服務(wù)器端和客戶端(通過(guò)JavaScript)發(fā)生。我們還想要確保我們的代碼遵循DRY原則(Don'tRepeatYourself,即不重復(fù)自己),這意味著我們應(yīng)該只在一處實(shí)施驗(yàn)證規(guī)則,然后使得我們的控制器、action方法和視圖來(lái)“兌現(xiàn)”這個(gè)承諾。接下來(lái)將使用VisualStudio2012,并利用ASP.NETMVC4來(lái)實(shí)現(xiàn)上述的場(chǎng)景。用戶也可以使用VisualStudio2010及ASP.NETMVC4來(lái)實(shí)現(xiàn)完全一樣的場(chǎng)景。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)Step01:實(shí)現(xiàn)FriendsController(沒(méi)有校驗(yàn))。首先在一個(gè)新的ASP.NETMVC4項(xiàng)目中添加一個(gè)簡(jiǎn)單的“Person”類,像下面這樣:2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證然后在項(xiàng)目中添加一個(gè)“FriendsController”控制器類,添加兩個(gè)“Create”action方法。第一個(gè)action方法是在對(duì)/Friends/CreateURL的HTTP-GET請(qǐng)求進(jìn)來(lái)時(shí)調(diào)用的,它會(huì)顯示一個(gè)空白的表單,用來(lái)輸入個(gè)人數(shù)據(jù);第二個(gè)action方法是在對(duì)/Friends/CreateURL的HTTP-POST請(qǐng)求進(jìn)來(lái)時(shí)調(diào)用的,它會(huì)將提交的表單輸入映射到一個(gè)Person對(duì)象,確認(rèn)沒(méi)有綁定錯(cuò)誤發(fā)生,如果是合法的,最終會(huì)將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中(在下文我們會(huì)實(shí)現(xiàn)相關(guān)的數(shù)據(jù)庫(kù)工作)。如果提交的表單輸入是不合法的,那么該action方法會(huì)重新顯示帶有錯(cuò)誤的表單。第二章模型2.4模型的數(shù)據(jù)校驗(yàn)2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)在實(shí)現(xiàn)了控制器之后,可以在VisualStudio中的其中一個(gè)action方法中右擊,在彈出的快捷菜單中選擇“添加視圖”命令,這會(huì)彈出“添加視圖”對(duì)話框,選擇自動(dòng)生成傳入對(duì)象為Person的“Create”視圖,如圖2.4所示。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證圖2.4構(gòu)建視圖第二章模型2.4模型的數(shù)據(jù)校驗(yàn)然后,VisualStudio會(huì)在我們項(xiàng)目的\Views\Friends\目錄中生成一個(gè)含有框架代碼的Create.aspx視圖文件。注意右邊這段代碼,它利用了ASP.NETMVC4中新的強(qiáng)類型HTML輔助方法。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)此時(shí),當(dāng)我們運(yùn)行該應(yīng)用,并且訪問(wèn)/Friends/CreateURL時(shí),將得到一個(gè)可以輸入數(shù)據(jù)的空白表單,如圖2.5所示。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證圖2.5Create.aspx視圖但是,由于我們還沒(méi)有在應(yīng)用中實(shí)現(xiàn)任何驗(yàn)證,因此無(wú)法阻止用戶在表單中輸入不合法的內(nèi)容,然后將其提交到服務(wù)器中。第二章模型2.4模型的數(shù)據(jù)校驗(yàn)Step02:使用DataAnnotation來(lái)啟用驗(yàn)證?,F(xiàn)在,讓我們來(lái)更新應(yīng)用,執(zhí)行一些基本的輸入驗(yàn)證規(guī)則。我們將在Person模型對(duì)象上實(shí)現(xiàn)這些規(guī)則,而不是在控制器或視圖中實(shí)現(xiàn)。在Person對(duì)象上實(shí)現(xiàn)這些規(guī)則的好處:這將確保這些驗(yàn)證在應(yīng)用中任何使用Person對(duì)象的場(chǎng)景中都會(huì)執(zhí)行(假如后來(lái)添加了編輯場(chǎng)景的話),從而避免在多處重復(fù)這些規(guī)則。ASP.NETMVC4允許開(kāi)發(fā)人員輕松地在模型或視圖模型類上添加聲明式驗(yàn)證,然后ASP.NETMVC在應(yīng)用中實(shí)施模型綁定操作時(shí),這些驗(yàn)證規(guī)則就會(huì)自動(dòng)執(zhí)行。舉例來(lái)說(shuō),讓我們更新Person類,在其中添加幾個(gè)驗(yàn)證特性,這樣做的話,將在文件的頂部添加一條對(duì)“System.ComponentModel.DataAnnotations”命名空間的“using”語(yǔ)句,然后在Person的屬性上使用[Required]、[StringLength]、[Range]和[RegularExpression]驗(yàn)證特性(這幾個(gè)特性都是在那個(gè)命名空間中實(shí)現(xiàn)的)。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)既然添加了驗(yàn)證特性到Person類,那么現(xiàn)在來(lái)重新運(yùn)行我們的應(yīng)用,此時(shí)需要查看在輸入不合法輸入項(xiàng)并將其提交回服務(wù)器時(shí)會(huì)發(fā)生什么,如圖2.6所示。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證圖2.6驗(yàn)證效果第二章模型2.4模型的數(shù)據(jù)校驗(yàn)從圖2.6我們可以看出,此例是一個(gè)不錯(cuò)的校驗(yàn)體驗(yàn),帶不合法輸入的文本元素以紅色高亮顯示,我們指定的驗(yàn)證錯(cuò)誤消息也顯示給了用戶。另外,表單還保留用戶原先輸入的數(shù)據(jù),這樣他們不用重新填寫(xiě)什么。上述內(nèi)容究竟如何實(shí)現(xiàn)呢?要理解這個(gè)行為,讓我們看一下處理表單的POST場(chǎng)景的Createaction方法。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)在我們的HTML表單提交回服務(wù)器時(shí),上面的方法就會(huì)被調(diào)用。因?yàn)樵揳ction方法接收一個(gè)“Person”對(duì)象為參數(shù),所以ASP.NETMVC會(huì)創(chuàng)建一個(gè)Person對(duì)象,自動(dòng)將傳輸進(jìn)來(lái)的表單輸入數(shù)值映射到該對(duì)象上。作為該過(guò)程的一部分,ASP.NETMVC還會(huì)檢查該P(yáng)erson對(duì)象上的DataAnnotation驗(yàn)證特性是否合法。如果一切都合法,那么我們代碼中的ModelState.IsValid檢查就會(huì)返回“true”,在這種情形下,我們(最終)將把該P(yáng)erson對(duì)象保存到數(shù)據(jù)庫(kù)中,然后重定向到主頁(yè)。如果Person對(duì)象上有任何驗(yàn)證錯(cuò)誤,那么action方法就會(huì)以該不合法Person對(duì)象的數(shù)據(jù)重新顯示表單,這是通過(guò)上面代碼片段中最后一條代碼語(yǔ)句實(shí)現(xiàn)的。然后,錯(cuò)誤消息就會(huì)顯示在我們的視圖中,因?yàn)镃reate表單在每一個(gè)<%:Html.TextBoxFor()%>輔助方法的調(diào)用旁都有一個(gè)<%:Html.ValidationMessageFor()%>輔助方法調(diào)用。Html.ValidationMessageFor()輔助方法會(huì)針對(duì)傳入視圖的任何不合法的模型屬性輸出合適的錯(cuò)誤消息。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)這個(gè)模式/方式有一個(gè)好處,就是非常容易配置。另外,它還允許我們輕松地添加或改變Person類上的驗(yàn)證規(guī)則,而不必改變控制器或視圖中的任何代碼。這個(gè)在一個(gè)地方指定驗(yàn)證規(guī)則,然后在所有的地方都會(huì)被承諾和遵守的能力,允許我們以最小的努力快速地發(fā)展我們的應(yīng)用和規(guī)則。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)Step03:啟用客戶端驗(yàn)證。目前我們的應(yīng)用只能做服務(wù)器端的驗(yàn)證,這意味著我們的終端用戶需要將表單提交到服務(wù)器才能看到任何驗(yàn)證錯(cuò)誤消息。ASP.NETMVC4的驗(yàn)證架構(gòu)中有一個(gè)非常不錯(cuò)的功能,那就是它同時(shí)支持服務(wù)器端和客戶端驗(yàn)證。如果要啟用這個(gè)功能,那么我們要做的就是在視圖中添加兩個(gè)JavaScript引用,即編寫(xiě)下面的代碼。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證在添加了上述代碼語(yǔ)句后,ASP.NETMVC4就會(huì)使用我們添加到Person類上的驗(yàn)證元數(shù)據(jù),為我們連接好客戶端JavaScript驗(yàn)證邏輯。這意味著,當(dāng)用戶使用<Tab>鍵跳出一個(gè)不合法的輸入元素時(shí),就會(huì)得到瞬時(shí)的驗(yàn)證錯(cuò)誤,如圖2.7(見(jiàn)下頁(yè))所示。第二章模型2.4模型的數(shù)據(jù)校驗(yàn)讓我們重新運(yùn)行應(yīng)用,在“FirstName”、“LastName”和“Email”文本框中輸入合法的數(shù)值,然后嘗試單擊“Create”按鈕,發(fā)現(xiàn)會(huì)有錯(cuò)誤提示,如圖2.8所示。注意,其實(shí)我們不必訪問(wèn)服務(wù)器就會(huì)得到超出年齡范圍值的瞬時(shí)錯(cuò)誤消息。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證圖2.7瞬時(shí)的驗(yàn)證錯(cuò)誤圖2.8提交后的驗(yàn)證錯(cuò)誤第二章模型2.4模型的數(shù)據(jù)校驗(yàn)這項(xiàng)技術(shù)帶來(lái)的好處是,我們不必編寫(xiě)自己的任何JavaScript就能啟用上面的驗(yàn)證邏輯。我們可以在一個(gè)地方指定規(guī)則,然后在整個(gè)應(yīng)用中得到執(zhí)行,即同時(shí)在客戶端和服務(wù)器端。值得讀者注意的是,由于安全的原因,服務(wù)器端驗(yàn)證規(guī)則總是執(zhí)行的,即使用戶啟用了客戶端支持。這是為了避免黑客嘗試?yán)@過(guò)客戶端規(guī)則,“哄騙”攻擊(spoof)用戶的服務(wù)器。ASP.NETMVC4中的客戶端JavaScript驗(yàn)證支持可與用戶在ASP.NETMVC應(yīng)用中使用的任何驗(yàn)證框架/引擎協(xié)作,它并不要求用戶使用DataAnnotation驗(yàn)證方式,所有的基礎(chǔ)設(shè)施是獨(dú)立于DataAnnotation的,可以與Castle驗(yàn)證器、EntLib驗(yàn)證應(yīng)用塊,或者用戶選擇的任何定制驗(yàn)證方案協(xié)作使用。如果用戶不想使用我們的客戶端JavaScript文件,那么也可以將其替換成jQuery驗(yàn)證插件,而使用那個(gè)庫(kù)。ASP.NETMVCFutures的下載包還包括針對(duì)ASP.NETMVC4服務(wù)器端驗(yàn)證框架啟用jQuery驗(yàn)證的支持。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)Step04:創(chuàng)建自定義的[Email]驗(yàn)證特性。.NET框架中的System.ComponentModel.DataAnnotations命名空間包括了眾多內(nèi)置驗(yàn)證特性。在上面的例子中,使用了其中的4個(gè):[Required]、[StringLength]、[Range]和[RegularExpression]。用戶也可以定義自己的定制驗(yàn)證特性,然后應(yīng)用它們。用戶可以通過(guò)繼承自System.ComponentModel.DataAnnotations命名空間中的ValidationAttribute基類,定義完全定制的特性。如果用戶只想擴(kuò)展它們的基本功能,那么也可以選擇繼承任何現(xiàn)有的驗(yàn)證特性。例如,為了幫助清理Person類中的代碼,我們也許想要?jiǎng)?chuàng)建一個(gè)新的[Email]驗(yàn)證特性,將檢查合法Email的正則表達(dá)式封裝起來(lái)。如果想要這樣做的話,那么只要像下列代碼那樣繼承RegularExpressionAttribute基類,然后用合適的Email正則表達(dá)式調(diào)用RegularExpressionAttribute基類的構(gòu)造器即可。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)然后將Person類更新成使用新的[Email]驗(yàn)證屬性,換掉先前使用的正則表達(dá)式,這樣會(huì)使得我們的代碼更簡(jiǎn)潔,封裝效果也更好。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)在建立定制的驗(yàn)證特性時(shí),用戶還可以在服務(wù)器端及客戶端指定通過(guò)JavaScript執(zhí)行的驗(yàn)證邏輯。除了建立可用于對(duì)象上個(gè)別屬性的驗(yàn)證特性外,還可以將驗(yàn)證特性用于類的層次,這允許對(duì)一個(gè)對(duì)象中的多個(gè)屬性實(shí)施驗(yàn)證邏輯。若要查看相關(guān)案例,可以參閱包含在默認(rèn)ASP.NETMVC4應(yīng)用項(xiàng)目模板AccountModels.cs/vb文件中的“PropertiesMustMatchAttribute”定制特性(在VisualStudio2010中,選擇“文件”→“新ASP.NETMVC4Web項(xiàng)目”,然后查詢?cè)擃?。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證第二章模型2.4模型的數(shù)據(jù)校驗(yàn)Step05:邏輯層的需求校驗(yàn)。校驗(yàn)中除了基本的長(zhǎng)度、必填、范圍等之外,還有符合邏輯要求的校驗(yàn)。這些校驗(yàn)除了用上面的自定義方法之外,還可以在控制層進(jìn)行相關(guān)的檢驗(yàn)。2.4.1非數(shù)據(jù)庫(kù)類DataAnnotation啟用驗(yàn)證在上述代碼段的相應(yīng)位置可以自己編寫(xiě)相關(guān)的方法進(jìn)行校驗(yàn)。第二章模型2.4模型的數(shù)據(jù)校驗(yàn)Step06:邏輯層的需求校驗(yàn)?,F(xiàn)在讓我們實(shí)現(xiàn)將朋友數(shù)據(jù)保存到數(shù)據(jù)庫(kù)所需的邏輯。至此,我們只用了簡(jiǎn)單的(plain-old)C#類(有時(shí)稱為“POCO”類,即“plainoldCLR(orC#)object”)。我們可以使用的一個(gè)方案是,編寫(xiě)一些單獨(dú)的持久代碼,將已經(jīng)編寫(xiě)好的現(xiàn)有類映射到數(shù)據(jù)庫(kù)。目前,像NHibernate這樣的對(duì)象關(guān)系映射(ObjectRelationalMapping,ORM)方案已經(jīng)可以非常好地支持POCO/PI這樣風(fēng)格的映射。隨.NET4發(fā)布的ADO.NET實(shí)體框架(EntityFramework,EF)也支持POCO/PI映射,而且就像NHibernate那樣,EF也能使用以“只用代碼”(codeonly)的方式(沒(méi)有映射文件,也不需要設(shè)計(jì)器)定義持久性映射的功能。如果我們的Person對(duì)象以這種方式
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 縫紉機(jī)結(jié)構(gòu)優(yōu)化與性能提升考核試卷
- 股票賬戶資產(chǎn)分配與生物科技產(chǎn)業(yè)投資協(xié)議
- 互聯(lián)網(wǎng)金融服務(wù)法律補(bǔ)充協(xié)議
- 農(nóng)業(yè)無(wú)人機(jī)電池租賃與無(wú)人機(jī)植保作業(yè)合同
- 金融科技證券分析師助理派遣與區(qū)塊鏈技術(shù)應(yīng)用合同
- 兒童圖書(shū)館文獻(xiàn)資源采購(gòu)與兒童教育服務(wù)協(xié)議
- 寵物醫(yī)院托管運(yùn)營(yíng)與品牌合作合同
- 電子商務(wù)利用補(bǔ)充協(xié)議規(guī)范物流配送
- 保險(xiǎn)理賠款結(jié)算與保險(xiǎn)理賠信息化建設(shè)協(xié)議
- 環(huán)保設(shè)備工藝保密補(bǔ)充協(xié)議書(shū)
- 第32屆全國(guó)中學(xué)生物理競(jìng)賽復(fù)賽試題
- 2025年中國(guó)腫瘤??漆t(yī)院行業(yè)市場(chǎng)規(guī)模及未來(lái)投資方向研究報(bào)告
- 抗腫瘤藥物的常見(jiàn)不良反應(yīng)及相應(yīng)對(duì)策
- 統(tǒng)編版語(yǔ)文四年級(jí)下冊(cè)第五單元教材解讀解讀與集體備課課件
- 課題申報(bào)書(shū):面向智能時(shí)代的中學(xué)生科學(xué)素養(yǎng)評(píng)價(jià)標(biāo)準(zhǔn)研究
- 2025年保密觀考試題庫(kù)及答案
- 農(nóng)藥銷售策略優(yōu)化路徑-全面剖析
- 用戶思維在產(chǎn)品創(chuàng)新中的應(yīng)用案例
- 消防維保考核標(biāo)準(zhǔn)
- 【初中化學(xué)】常見(jiàn)的鹽-2024-2025學(xué)年九年級(jí)化學(xué)科粵版(2024)下冊(cè)
- 中國(guó)教育社會(huì)問(wèn)題
評(píng)論
0/150
提交評(píng)論