鮮為人知的ASP.NET MVC 2.0框架高效之謎
原創(chuàng)【51CTO獨(dú)家特稿】要想建立開發(fā)環(huán)境,你需要安裝Visual Studio 2008/2010 Beta 2,以及SQL Express 2005(可免費(fèi)從MSDN下載)和MVC 2.0框架。我把本文中的示例Web應(yīng)用命名為“Employee Master Information”。51CTO-.NET頻道向您推薦《ASP.NET MVC框架視頻教程》以便于您更好的理解本文。
使用該應(yīng)用程序,你可以輸入新員工數(shù)據(jù),編輯現(xiàn)有員工數(shù)據(jù),可以查看特定員工數(shù)據(jù),和從數(shù)據(jù)庫(kù)中給刪除任意員工信息。該應(yīng)用程序還使用了ASP.NET的Membership Provider來(lái)創(chuàng)建新用戶和認(rèn)證已有用戶,客戶端驗(yàn)證通過JavaScript實(shí)現(xiàn)。
圖1
創(chuàng)建MVC項(xiàng)目、數(shù)據(jù)庫(kù)和數(shù)據(jù)模型
在此前的ASP.NET MVC 2.0文章中,我討論過如何使用Visual Studio 2008編輯器來(lái)創(chuàng)建一個(gè)MVC Web應(yīng)用程序。在本篇文章中我使用VS2008(.NET框架3.5)創(chuàng)建的項(xiàng)目名稱為“MyMvcSample”。創(chuàng)建了MVC 2.0網(wǎng)站后,接下來(lái)將是創(chuàng)建數(shù)據(jù)庫(kù)和數(shù)據(jù)模型。
圖2
右鍵點(diǎn)擊項(xiàng)目的“App_Data”文件夾,并向你的解決方案增加一個(gè)“SQL Server Database”對(duì)象。如果你的開發(fā)環(huán)境中沒有安裝“SQL Express”,你不會(huì)在“Template”窗口中看到這個(gè)選項(xiàng)。將SQL Express數(shù)據(jù)庫(kù)的名稱指定為MySampleDatabase.mdf,點(diǎn)擊“Add”按鈕后,一個(gè)新數(shù)據(jù)庫(kù)將被添加到App_Data文件夾中。現(xiàn)在從“View”菜單中打開“Server Explorer”;你將看到MySampleDatabase.mdf數(shù)據(jù)庫(kù)已經(jīng)存在。右鍵點(diǎn)擊該數(shù)據(jù)庫(kù)下的“Tables”對(duì)象,增加一個(gè)名為“tblEmployee”的新表。在該表中添加以下列。
- EmployeeName nvarchar(100)
- EmployeeSalary numeric(18, 2)
- EmployeeId int (Primary Key)
- Department nvarchar(100)
- Age int
- Skillset nvarchar(1000)
- Role nvarchar(50)
對(duì)于主鍵列,你需要修改兩個(gè)屬性:將“Identity Specification”的值從“No”改為“Yes”,將“Identity Increment”從0改為1。表創(chuàng)建完后,增加一些示例數(shù)據(jù)以供測(cè)試用。
圖3
接下來(lái)你需要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)模型,右鍵點(diǎn)擊“Model”文件夾,并增加一個(gè)新條目。從模板列表中選擇“ADO.NET Entity Data Model”。在本示例中我的模型名稱為“DataModel.edmx”。點(diǎn)擊增加按鈕向你的解決方案添加該模型。接下來(lái)你將看到一個(gè)向?qū)Ы缑妫鼘⒅笇?dǎo)你為剛才創(chuàng)建的模型增加數(shù)據(jù)源。選擇“Generate from Database”并點(diǎn)擊下一步。
接下來(lái)你需要選擇合適的數(shù)據(jù)源,從列表中選擇此前創(chuàng)建的“MySampleDatabase.mdf”,并為該數(shù)據(jù)源指定一個(gè)名稱。在解決方案web.config文件下的“ConnectionStrings”標(biāo)簽下,你將看到一個(gè)自動(dòng)生成的包含數(shù)據(jù)源名稱和連接字符串的條目。在本例中我的連接名稱是“MySampleDatabaseEntities”。接下來(lái),檢查tblEmployee,并向你的模型提供一個(gè)命名空間名稱。
圖4
在模型創(chuàng)建后,在模型查看器中打開DataModel.edmx。該查看器將幫助你查看模型數(shù)據(jù)源,以及模型和數(shù)據(jù)庫(kù)之間的字段映射。使用模型查看器你還可以更改模型屬性、字段名和數(shù)據(jù)類型。這個(gè)“Employee”模型將被在Controller類中使用,來(lái)增加、編輯和刪除數(shù)據(jù)庫(kù)中的員工詳細(xì)信息。DataModel.edmx是一個(gè)ADO.NET Entity Framework對(duì)象,可以在進(jìn)行插入、更新或刪除數(shù)據(jù)時(shí)減少代碼編寫工作量。ADO.NET Entity Framework還支持LINQ,因此你可以在業(yè)務(wù)對(duì)象上編寫查詢類的SQL,而無(wú)需編寫存儲(chǔ)過程來(lái)抓取數(shù)據(jù)。
圖5
#p#
創(chuàng)建控制器
控制器將會(huì)用到 Microsoft.Web.Mvc.Build.dll和Microsoft.Web.Mvc.dll中的類。因此在編譯應(yīng)用程序之前,應(yīng)檢查上述兩個(gè)動(dòng)態(tài)庫(kù)已經(jīng)在你的bin文件夾下。
對(duì)于增加、編輯、刪除和查看員工職責(zé)詳細(xì)信息等操作,我已經(jīng)在我的HomeController中增加了“Get”和“Post”函數(shù)。控制器中的每一個(gè)函數(shù)都被關(guān)聯(lián)到一個(gè)視圖(.ASPX頁(yè)面),例如為了查看員工列表,我編寫了“Index”函數(shù)來(lái)返回員工列表信息,該信息將被顯示在名為“Index.aspx”的視圖中。要想顯示某個(gè)特定員工的數(shù)據(jù),則會(huì)調(diào)用Details函數(shù)。
- Function Details(ByVal id As Integer) As ActionResult
- Dim objEditEmployee = (From c In objDatabaseEntities.EmployeeSet
- Where c.EmployeeId = id Select c).FirstOrDefault()
- Return View(objEditEmployee)
- End Function
LINQ被用來(lái)查詢業(yè)務(wù)對(duì)象和從Employee List模型中查找某個(gè)特定員工。通過使用“Return View”,這個(gè)員工對(duì)象將被發(fā)回到相應(yīng)的視圖。至于創(chuàng)建一個(gè)新員工,我也為“Create”方法創(chuàng)建了“Get”和“Post”兩個(gè)版本。該方法的Get版將重定向到一個(gè)空白Employee頁(yè)面/視圖,由用戶來(lái)輸入員工詳細(xì)信息,而Post版的“Create”函數(shù)將使用我們之前創(chuàng)建的Employee Model對(duì)象保存數(shù)據(jù)庫(kù)中的員工詳細(xì)信息。51C TO-.NET頻道向您推薦《LINQ教程-LINQ to SQL技術(shù)精解》專題。
圖6
我對(duì)Create.aspx頁(yè)面中的所有輸入字段都添加了合適的客戶端驗(yàn)證代碼。如果新輸入的員工姓名已經(jīng)存在,則數(shù)據(jù)不會(huì)被插入到數(shù)據(jù)庫(kù)中。
- Function Create(ByVal objEmployee As Employee) As ActionResult
- Try
- Dim objExtEmployee = (From c In objDatabaseEntities.EmployeeSet Where
- c.EmployeeName = objEmployee.EmployeeName Select c).FirstOrDefault()
- If objExtEmployee Is Nothing Then
- objDatabaseEntities.AddToEmployeeSet(objEmployee)
- objDatabaseEntities.SaveChanges()
- Return RedirectToAction("Index")
- End If
- Catch
- Return View()
- End Try
- Return RedirectToAction("Index")
- End Function
對(duì)于編輯員工詳細(xì)信息,我也創(chuàng)建“Get”和“Post”版的Edit函數(shù),不過我在HomeController本身中增加了驗(yàn)證機(jī)制。如果驗(yàn)證失敗的話,我會(huì)使用Modelstate.Addmodelerror()函數(shù)來(lái)向相應(yīng)視圖拋出一個(gè)錯(cuò)誤信息。
- Protected Sub ValidateContact(ByVal EmployeeToValidate As Employee)
- If EmployeeToValidate.EmployeeName.Trim().Length = 0 Then
- ModelState.AddModelError("Employee Name", "Employee name is required
- field.")
- End If
- If EmployeeToValidate.EmployeeId.ToString().Trim().Length = 0 Then
- ModelState.AddModelError("Employee Id", "Employee Id is required field.")
- End If
- If (EmployeeToValidate.Department.Length = 0) Then
- ModelState.AddModelError("Employee Department", "Employee Department is
- required field.")
- End If
- If (EmployeeToValidate.EmployeeSalary.ToString().Length = 0) Then
- ModelState.AddModelError("Employee Salary", "Employee Salary is required
- field.")
- End If
- If (EmployeeToValidate.Age.ToString().Length = 0) Then
- ModelState.AddModelError("Employee Age", "Employee Age is required field.")
- End If
- If (EmployeeToValidate.Skillset.ToString().Length = 0) Then
- ModelState.AddModelError("Employee Skillset", "Employee Skillset is required
- field.")
- End If
- If (EmployeeToValidate.Skillset.ToString().Length = 0) Then
- ModelState.AddModelError("Employee Role", "Employee Role is required
- field.")
- End If
- End Sub
在刪除員工列表方面,我只增加了一個(gè)Get版,并在視圖中增加了必要的JavaScript驗(yàn)證代碼(確認(rèn)信息)。
創(chuàng)建視圖
在一個(gè)ASP.NET MVC應(yīng)用中,所有入站的瀏覽器請(qǐng)求都被映射到控制器行為上。控制器行為可能會(huì)返回一個(gè)視圖。與ASP.NET頁(yè)面不一樣,MVC視圖后端沒有任何代碼。你可以通過右鍵點(diǎn)擊控制器post函數(shù)并選擇“view”選項(xiàng)來(lái)創(chuàng)建視圖。向項(xiàng)目增加視圖的第二種方法是,右鍵點(diǎn)擊你的視圖文件夾,并增加一個(gè)新視圖。默認(rèn)情況下,沒有后端代碼的.ASPX就是這些視圖。你可以在項(xiàng)目中增加一個(gè).ASCX文件和HTML文件作為視圖。
圖7
本例中,我創(chuàng)建了4個(gè)不同的視圖來(lái)實(shí)現(xiàn)增加、編輯、列舉和顯示員工詳細(xì)信息,它們都是強(qiáng)類型視圖。我使用了HTML幫助類,在視圖中創(chuàng)建HTML對(duì)象和驗(yàn)證信息來(lái)驗(yàn)證客戶端數(shù)據(jù)項(xiàng)。以下代碼顯示了如何使用HTML幫助類創(chuàng)建一個(gè)HTML輸入控制和添加驗(yàn)證。
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.EmployeeName) %>
- <%= Html.ValidationMessageFor(Function(model) model.EmployeeName) %>
- </div>
我試用HTML輔助方法ActionLink來(lái)實(shí)現(xiàn)視圖導(dǎo)航,使用Html.Encode()來(lái)將“<”和“>”等特殊字符編碼成可以在網(wǎng)頁(yè)上正常顯示的字符。微軟推薦使用HTML.Encode()方法來(lái)防止JavaScript注入攻擊。以下是向數(shù)據(jù)庫(kù)增加一名新員工的代碼。
- <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
- <h2>Create Employee</h2>
- <%=""%>
- <% Using Html.BeginForm()%>
- <fieldset>
- <legend>Details to Enter</legend>
- <div class="editor-label">
- <%=Html.LabelFor(Function(model) model.EmployeeName)%>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.EmployeeName) %>
- <%= Html.ValidationMessageFor(Function(model) model.EmployeeName) %>
- </div>
- <div class="editor-label">
- <%= Html.LabelFor(Function(model) model.EmployeeSalary) %>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.EmployeeSalary) %>
- <%= Html.ValidationMessageFor(Function(model) model.EmployeeSalary) %>
- </div>
- <div class="editor-label">
- <%= Html.LabelFor(Function(model) model.EmployeeId) %>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.EmployeeId) %>
- <%= Html.ValidationMessageFor(Function(model) model.EmployeeId) %>
- </div>
- <div class="editor-label">
- <%= Html.LabelFor(Function(model) model.Department) %>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.Department) %>
- <%= Html.ValidationMessageFor(Function(model) model.Department) %>
- </div>
- <div class="editor-label">
- <%= Html.LabelFor(Function(model) model.Age) %>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.Age) %>
- <%= Html.ValidationMessageFor(Function(model) model.Age) %>
- </div>
- <div class="editor-label">
- <%= Html.LabelFor(Function(model) model.Skillset) %>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.Skillset) %>
- <%= Html.ValidationMessageFor(Function(model) model.Skillset) %>
- </div>
- <div class="editor-label">
- <%= Html.LabelFor(Function(model) model.Role) %>
- </div>
- <div class="editor-field">
- <%= Html.TextBoxFor(Function(model) model.Role) %>
- <%= Html.ValidationMessageFor(Function(model) model.Role) %>
- </div>
- <p>
- <input type="submit" value="Create" />
- </p>
- </fieldset>
- <% End Using %>
- <div>
- <%=Html.ActionLink("Back to Employee List", "Index")%>
- </div>
- </asp:Content>
結(jié)束語(yǔ)
對(duì)于那些剛接觸ASP.NET Web編程的開發(fā)者來(lái)說(shuō),學(xué)習(xí)MVC框架并不是一件難事。MVC框架應(yīng)用程序的代碼也非常容易維護(hù)。另外,開發(fā)者還可以在該框架中使用測(cè)試驅(qū)動(dòng)開發(fā)方法。
原文題目:Create a Web App Using ASP.NET MVC 2.0 Framework
【編輯推薦】