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