asp.netMVC的出現,讓前台和后台都得到了一種回歸,編程基礎扎實的同學學MVC或許要比webform要輕松N倍,你不在為麻煩的控件配置而焦慮,這里只有純凈的前后台代碼。剛剛開始學習MVC,所以就加上自己的理解,翻譯一些比較好的書籍和同學們一起來分享MVC3的精彩內容。如果有不合適的地方,大家可以指正和指導下我,我會馬上修改。英文的資料看起來很容易但是要是用來寫成文字,發現遠遠超過了讀前三章的時間,今天我幾乎寫了3.5個小時的博客到后面有點小浮躁,不知道翻譯有沒有出入,如有不妥大家都可以指正。
你的第一個MVC應用程序
領悟一個軟件開發框架的最佳方式是深入內部並使用它。在這本章中,您將使用ASP.NET MVC框架創建一個簡單的數據輸入應用程序。我們要一步步的讓你看到如何構建一個ASP.NET MVC應用程序。為了簡單易懂,我們將跳過一些技術細節的時刻,但不要擔心,如果你是初識MVC,你會發現很多讓你感興趣的。在這里我們應用但沒有過多的解釋(這章的重點不是原理),在后面我們提供各個參考的章節,在這里你可以找到所有的細節。
創建一個新的ASP.NET MVC項目
我們將開始在Visual Studio中創建一個新的MVC項目。從“文件”中選擇“新建項目”菜單打開“新建項目”對話框。如果您選擇的網頁模板,你會看到MVC 3安裝程序ASP.NET MVC 3 Web應用程序創建一個新的項目,如圖3-1所示。
圖3-1。在Visual Studio中的MVC 3項目模板
設置的新項目P名稱為artyInvites,並單擊“確定”按鈕繼續。你會看到一個對話框,如圖3-2所示,要求您選擇三種不同類型的MVC項目模板。
如果僅僅是最低要求的文件和文件夾的MVC 3 應用程序你可以選擇創建一個 Empty項目。Internet應用程序“選項創建一個小的示例應用程序,您可以在他的基礎上修改和建立自己的應用程序。它包括用戶注冊和認證,導航和一致的視覺風格。 Intranet應用程序選項是類似於Internet應用程序,但其設計中使用了對用戶進行身份驗證域/ Active Directory基礎結構的環境。在本章中,我們將讓事情變得簡單易懂。選擇“Empty”選項,取消選中的HTML5語義標記選項,並單擊“確定”以創建新的項目。
注意:在圖3-2中的模板選項中,你可以看到一個下拉菜單,在這里你可以指定需要的視圖引擎。正如我們在第1章,MVC 3包含一個新的Razor視圖引擎和改進的ASPX視圖引擎,這是我們將在本書中群不全部使用Rozor。我們建議你和我們一樣這么選擇。但是,如果你想使用常規的ASP.NET視圖引擎(又稱為ASPX引擎),您也可以選擇它。
一旦在Visual Studio創建的項目,你會在VS的“解決方案資源管理器”窗口看到一些文件和文件夾結構。這是默認的MVC 3項目的結構。您可以嘗試運行
現在應用程序從“調試”菜單中選擇“開始調試”(如果提示您啟用調試時,只要按一下“確定”按鈕)。您可以看到圖3-3中的結果。應為我們開始使用了Empty項目模板,應用程序不包含任何內容,所以我們可以看到一個404 Not Found錯誤。
圖3-3。試圖運行一個空項目
當你完成后,一定要停止調試,關閉顯示錯誤瀏覽器窗口(當然也可以不關閉下次生成項目后刷新瀏覽器),回到Visual Studio,並從“調試”菜單中選擇“停止調試。在MVC架構中添加一個控制器,由控制器處理傳入的請求。在ASP.NET MVC中,控制器簡單的C#類(通常繼承自System.Web.Mvc.Controller的,這是asp.netMVC內置控制器基類)。每個公共方法被稱為控制器的action方法,這意味着你可以通過一些URL從Web調用和執行一項操作(action)。 MVC約定是把
所有的控制器放在名為Controllers的文件夾中,這是我們創建項目時,由Visual Studio創建的控制器。你並不需要遵循本約定或其他大多數MVC約定,但我們建議你這樣操作,並不是簡單的因為這將有助於你理解這本書中的例子。
右鍵單擊Controllers文件夾中的Visual Studio解決方案資源管理器窗口,並從彈出的菜單中選擇“添加”,然后控制器,添加一個控制器到我們的項目中,如圖3-4所示。
圖3-4。添加控制器的MVC項目
當出現“添加控制器”對話框時,將名稱設置為HomeController的,如圖3-5所示。這又是一個約定:我們給控制器的名稱應該是描述性和以Controller結尾。
圖3-5。設置為控制器的名稱
Scaffolding options中給我們預制了控制器使用常見功能的模板。我們不打算使用此功能,因此要確保在“模板”菜單中選擇Empty controller,如圖所示。 注意:如果你沒有看到,因為它是在圖3-5所示的“添加控制器”對話框中,你可能忘了安裝工具更新MVC 3。有關詳細信息,請參閱第2章。
單擊“添加”按鈕,創建一個控制器。Visual Studio將在Controller文件夾中創建一個新的名為HomeController.cs的C#代碼文件,打開它進行編輯時,你可以看到,這個被稱為HomeController的類,它是在System.Web.Mvc命名空間下定義的。編輯這個文件中的代碼,如下3-1。
Listing 3-1. 修改 HomeController 類
using System.Web.Mvc; namespace PartyInvites.Controllers { public class HomeController : Controller { public string Index() { return "Hello, world"; } } }
當然這不足以令人興奮的,但對剛剛學習MVC的童鞋,這是一個很好的開端。我們創建了一個名為為Index的action方法,它會返回字符串“Hello,world”。再次運行該項目(由從Visual Studio的“調試”菜單中選擇“啟動調試)。瀏覽器將顯示的結果。如圖3-6所示。
圖3-6 瀏覽器輸出結果
了解路由
除了模型,視圖和控制器,MVC應用程序也使用ASP.NET路由系統,決定如何將URL映射到特定的控制器和action中。
當Visual Studio創建的MVC項目,它會添加一些默認路由,您可以使用下面的任何一個URL請求,他們將被引導到了HomeController的Index action:
• /
• /Home
• /Home/Index
當瀏覽器請求http://yoursite/的或http://yoursite/Home,將調用HomeController的Index方法。輸出字符串“Hello,world”。這是一個很好的遵循MVC約定的例子。在這種情況下,我們將有一個名叫HomeController的控制器,這將是我們的MVC應用程序的起點。有一個名叫HomeController的,這將是我們的MVC應用程序的起點。假設我們遵循了這一約定Visual Studio會創建一個新的項目的缺省路由,我們的URLS前面的列表中得到支持。如果我們沒有依循慣例,我們將需要手動修改的路由指向需要的控制器。對於這個簡單的例子中,默認的配置就夠了。
提示:您可以通過打開的Global.asax.cs文件查看和編輯您的路由配置。在第7章中,您將設置自定義路由表項,並在第11章中,你會學到更多關於路由可以做什么。
渲染網頁
前面的例子不是輸出HTML而是簡單的字符串“Hello,world”。我們需要創建一個視圖瀏覽器請求,響應HTML。
創建和渲染視圖
我們需要做的第一件事情就是修改我們的索引中的操作方法,如清單3-2所示。
清單3-2。修改控制器渲染視圖
using System.Web.Mvc; namespace PartyInvites.Controllers { public class HomeController : Controller { public ViewResult Index() { return View(); } } }
在清單3-2以粗體顯示。當我們返回一個ViewResult對象從一個action方法,我們我們通過調用視圖的方法創建的ViewResult
(不帶任何參數)發出指令讓MVC渲染視圖。這將使MVC為該action呈現的默認視圖。如果您運行的應用程序,你可以看到MVC框架試圖找到一個默認的視圖顯示的錯誤信息如圖3-7中所示。
如圖3-7所示。 MVC框架試圖找到一個默認的視圖
錯誤消息是最有幫助的。它不僅解釋無法為某個action方法找到一個MVC視圖,這又是一個很好的MVC約定“:view與action方法的命名約定。我們的action方法稱為Index,你可以從圖3-7中看到的MVC正試圖在“視圖”文件夾中找到不同的文件所有相同名稱。
創建一個視圖,用鼠標右鍵單擊在HomeController.cs代碼文件的操作方法(無論是在方法的名稱或內部的方法體),從彈出的菜單中選擇“添加視圖”。這將打開添加視圖“對話框,如圖3-8所示。
取消選中“使用布局或母版頁。我們不使用布局,在這個例子中,但我們會看到他們在第5章中使用。點擊“添加”按鈕,Visual Studio將在 View/ Home創建一個新的視圖文件Index.cshtml。如果你回頭看看圖3-7中的錯誤信息,你會看到,被搜查的路徑之一與我們剛創建的文件相匹配。
提示:CSHTML的文件擴展名表明他是一個由Razor視圖引擎處理的。老版本的MVC依靠ASPX視圖引擎,視圖文件.aspx擴展名。
打開Index.cshtml文件進行編輯。這個文件主要包含HTML。 其中有一段代碼塊如下:
@{ Layout = null; }
這是一個將被Razor視圖引擎解釋的代碼塊。它只是告訴Razor視圖引擎,我們選擇不使用母版頁。
如圖Index.cshtml文件在清單3-3中所示
@{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Index</title> </head> <body> <div> Hello, world (from the view) </div> </body> </html>
添加一些簡單的信息。選擇“開始”,從“調試”菜單中進行調試運行並測試應用程序。您應該會看到類似圖3-9。
當我們第一次創建Index的action方法,他除了輸出簡單的字符串返回給瀏覽器什么都沒干。現在,該方法返回一個ViewResult類型的對象,指示MVC渲染視圖,並返回HTML。我們沒有並沒有指定MVC視圖應該怎么做,所以它使用的命名約定自動匹配。相應的View具有和controller文件夾中的action方法一樣的名稱——~/Views/Home/Index.cshtml.我們可以讓action方法返回其他結果(除了字符串的ViewResult對象)。例如,如果我們返回RedirectResult,瀏覽器重定向到另一個URL。如果我們返回HttpUnauthorizedResult,我們強制用戶登錄。他們都繼承自ActionResult類。action result 體系讓我們封裝和復用常見的相應操作更加方便。我們將通過這本書告訴你更多關於他們復雜的使用。
添加動態輸出
當然,對於整個Web應用程序平台的構建和動態顯示輸出來看,在MVC,准備響應數據是控制器的工作,呈現HTML則是視圖的工作。數據從控制器傳遞到視圖。
數據從控制器傳遞到視圖的方法之一是通過使用ViewBag對象。這是一個Controller基類的成員。 ViewBag是一個動態對象,你可以指定任意的屬性,並使這些值呈現在任何視圖中。清單3-4演示
以這種方式通過一些簡單的動態數據。
Listing 3-4. Setting Some View Data using System; using System.Web.Mvc; namespace PartyInvites.Controllers { public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewBag.Greeting = hour < 12 ? "Good morning" : "Good afternoon"; return View(); } } }
以粗體顯示的語句我們提供的數據的視圖。如清單3-5所示。
Listing 3-5. Retrieving a ViewBag Data Value @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Index</title> </head> <body> <div> @ViewBag.Greeting, world (from the view) </div> </body> </html>
清單3-5是一個Razor代碼塊,檢索保存在的ViewBag的greeting屬性。該屬性名稱沒有什么特別的之處,你可以更換任何自定義屬性名稱(它的作用是相同的)。當然,你可以在視圖中以相同的方式獲取多個數據值的。
提示:我們並不需要終止Razor代碼塊。我們以@字符開始,然后添加我們的C#代碼。這是Razor一個很好的特性。這樣更具可讀性,我們不在需要使用煩人的<%和%>標記。
如果我們再次運行該項目,我們可以看到我們的第一個動態的MVC輸出,如圖3-10所示。
創建一個簡單的數據錄入應用程序
在本章的剩余部分,我們將通過建立一個簡單的數據輸入應用程序探討更基本的MVC功能。在本節我們將加快進度。我們的目標是展示MVC的應用, 所以我們跳過一些的解釋是后台是如何工作的的話題。但是不要擔心,在后面的章節中,我們將再次深入這些話題。
設置場景
我們會想象,一個朋友已經決定舉辦一個除夕派對,她要我們創建了一個網站,讓她受邀者使用電子郵件回復。她要求四個主要特點:
- 顯示有關晚會的一個主頁
- 提交RSVP的表單
- 驗證RSVP的格式,之后將顯示一個感謝頁面
- 完成后回函電子郵件
在下面的章節中,我們將建立在已經創建的MVC項目中,我們在本章開始添加這些功能。通過運用我們在前面的內容中,我們可以添加一些HTML到我們現有的視圖來描述party的細節,如清單3-6所示。
Listing 3-6. Displaying Details of the Party @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Index</title> </head> <body> <div> @ViewBag.Greeting, world (from the view) <p>We're going to have an exciting party.<br /> (To do: sell it better. Add pictures or something.) </p> </div> </body> </html>
您運行的應用程序,你會看到party的細節,如圖3-11所示。
設計一個數據模型
在MVC中,M代表的是模型,它是應用程序最重要的的一部分。該模型是將真實世界的對象,過程和規則抽象的定義在程序域中,通常被稱為一個域模型,該模型包含了C#對象已知的域對象),使我們可以在應用程序和方法中對它們進行操作,並通過一些方式可以將其信息回饋給客戶端。一個精心設計的模型是一個設計良好的MVC應用程序的開始,現在我們把重點放在添加控制器和視圖。我們並不需要為PartyInvites應用程序添加一個復雜的模型,這里我們只是用一個簡單的名為GuestResponse域模型我們將使用用於負責存儲,驗證,並確認RSVP。
添加一個模型類
MVC的約定是,一個模型的類被放置在〜/ Models文件夾。在“解決方案資源管理器”窗口中右鍵單擊“模型,並選擇”添加類從彈出的菜單。設置文件名GuestResponse.cs,並單擊“添加”按鈕來創建類。按照清單3-7編輯類的內容。
提示 您可能已經注意到,WillAttend屬性是一個可為空的布爾值,這意味着它可能是true,false,或者為null。“添加驗證”我們將在后面的章節中解釋“添加驗證”的理由。
鏈接操作方法
我們的應用程序包括了RSVP表單,所以我們需要添加一個鏈接到它從我們的Index.cshtml視圖,如清單3-8所示。
Listing 3-8. Adding a Link to the RSVP Form @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Index</title> </head> <body> <div> @ViewBag.Greeting, world (from the view) <p>We're going to have an exciting party.<br /> (To do: sell it better. Add pictures or something.) </p> @Html.ActionLink("RSVP Now", "RsvpForm") </div> </body> </html>
Html.ActionLink是一個HTML輔助方法。MVC框架集中方便的選擇輔助方法的渲染HTML鏈接,文本輸入框,復選框,甚至是自定義的控件。 ActionLink方法有兩個參數:第一個是要顯示的文本的鏈接,第二個是要執行的action。當用戶點擊的鏈接,您可以看到在圖3-12中添加的鏈接效果。我們將在第15和第16章中講解HTML輔助方法。
當你的鼠標放在瀏覽器中的鏈接上時,你會看到該鏈接指向ttp://yourserver/Home/RsvpForm。 Html.ActionLink方法檢查我們的應用程序的URL
路由配置和執行HomeControls中的名為ResvpForm的action。注意,不同於傳統的ASP.NET應用程序,MVC的URL不對應於物理的文件。每個action方法都有其自己的URL,MVC使用ASP.NET路由系統把這些urls指向創建的action方法.如果您單擊的鏈接,你會看到一個404 Not Found錯誤.因為我們還沒有創建的action方法
對應的/Home/RsvpForm中的URL。為此,我們要給HomeController類添加一個名為RsvpForm的方法,如清單3-9所示。
Listing 3-9. Adding a New Action Method to the Controller using System; using System.Web.Mvc; namespace PartyInvites.Controllers { public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewData["greeting"] = hour < 12 ? "Good morning" : "Good afternoon"; return View(); } public ViewResult RsvpForm() { return View(); } } }
添加一個強類型的視圖
我們給RsvpForm方法添加的視圖,但我們會做一些調整,我們要創建一個強類型的視圖。一個強類型的視圖的目的是渲染一個特定的域類型,如果我們指定的類型,我們使用(在這個例子中是GuestResponse),MVC可以提供一些有用的快捷方式,使其更容易。
注意 在做其他事情之前,請確保您的MVC項目被編譯。如果您已經創建了GuestResponse類,但沒有編譯,MVC將無法創建一個強類型的視圖對應這種類型。
從Visual Studio生成“菜單中選擇”生成解決方案編譯您的應用程序。
右鍵單擊里面的RsvpForm方法,並從彈出的菜單中選擇“添加視圖”。在“添加視圖”對話框中,選中“創建一個強類型的視圖選項,並從下拉菜單中選擇GuestResponse。取消選中“使用布局或母版頁,並確保選擇Razor引擎布局模板“選項設置為空,如圖如圖3-13所示。
單擊“添加”按鈕,創建新的視圖。Visual Studio將打開RvspForm.cshtml文件,你會看到,它是一個一個@ modelRoazr格式開頭的HTML文件。正如你將看到
當前這已經是一個強類型的視圖,它提供的很多的便利。
建立表格
現在,我們已經創建了強類型的視圖,我們可以在RsvpForm.cshtml文件中編寫一個HTML表單用於編輯GuestResponse對象。如下清單3-10。
Listing 3-10. Creating a Form View @model PartyInvites.Models.GuestResponse @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>RsvpForm</title> </head> <body> @using (Html.BeginForm()) { <p>Your name: @Html.TextBoxFor(x => x.Name) </p> <p>Your email: @Html.TextBoxFor(x => x.Email)</p> <p>Your phone: @Html.TextBoxFor(x => x.Phone)</p> <p> Will you attend? @Html.DropDownListFor(x => x.WillAttend, new[] { new SelectListItem() {Text = "Yes, I'll be there", Value = bool.TrueString}, new SelectListItem() {Text = "No, I can't come", Value = bool.FalseString} }, "Choose an option") </p> <input type="submit" value="Submit RSVP" /> } </body> </html>
對於GuestResponse模型類的每個屬性,我們使用一個HTML輔助方法渲染一個合適的HTML input標簽。這些方法會讓你選擇輸入元素的屬性,涉及到
使用lambda表達式,例如:
@ Html.TextBoxFor(X => x.Phone)
不要擔心,如果你不熟悉C#lambda表達式。我們在第5章中提供了一個概述。
HTML輔助方法生成的HTML生成一個input 元素,設置它的type為text,並設置id和name屬性為Phone,而這些都是以的域模型的屬性名為准,如下
屬性,如下所示:
<input id="Phone" name="Phone" type="text" value=""
這個方便的特性依賴於此處的RsvpForom方法對象的視圖是強類型的,我們已經告訴過MVC,操作的是GuestResponse類型,我們要渲染這個View。
另一種替換lambda表達式的方法是使用一個名稱相同的字符串類型的屬性,例如:
@ Html.TextBox(“電子郵件”)
我們發現,我們的lambda表達式技術可以防止輸錯的模型名稱和相應的屬性。Visual Studio會彈出智能提示讓我們挑選的合適的並自動完成關聯,如圖3-14所示。
另一種方便的輔助方法是Html.BeginForm,生成一個HTML表單元素並配置回發的操作方法。因為我們還沒有傳遞任何參數給該方法,它會認為我們要回發到相同的URL。一個使用它的絕招是用C#using 聲明包裝它,例如:
@using (Html.BeginForm())
{
...form contents go here...
}
通常情況下,這樣的應用時,使用的語句確保一個 超出范圍對象被及時釋放。它常用於數據庫操作中,例如,在完成一個查詢以確保他們 盡快關閉,(這里的using關鍵字不同於講一個外部類用一個命名空間引入到一個類的作用域中的using),而不是丟棄對象, HtmlBeginForm helper在HTML表單元素超出的范圍自動將其釋放。這意味着該 Html.BeginForm輔助方法創建的表格元素,像這樣兩個部分:
<form action="/Home/RsvpForm" method="post">
形式內容到這里...
</ FORM>
不要擔心,如果你不熟悉C#對象的處理。這里的關鍵是演示如何創建使用HTML輔助方法的一種形式。
提示 ASP.NET WebForm只支持一個服務器端的控件,通常注明為<form runat="server">,這是一個視圖狀態數據和回傳邏輯的容器。MVC則不需要這種的形式。我們只需要使用使用普通的HTML標簽,你可以在一個視圖中素心所欲的使用。而不必擔心沒有視圖狀態(ViewState)或其他隱藏的表單元素的id值分配錯位。當您運行的應用程序,然后單擊“現在的RSVP鏈接,你可以看到的形式在RsvpForm視圖。圖3-15顯示了結果。
請注意:這不是一本關於CSS網頁設計。在大多數情況下,我們將要創建的例子,它的外觀可以被描述為鄉巴佬(雖然我們喜歡這個詞的經典之作,但不是輕蔑)。MVC視圖生成非常干凈和純潔的HTML,你可以完全控制他們被分配到的布局元素和類,所以你可以使用設計工具或現成的模板,讓你的MVC項目漂亮。
我們將創建另外一個強類型的視圖,因此在“添加視圖”對話框中,我們選擇的視圖模型必須與傳遞給視圖中使用的View方法的類一致,所以必須從Modles class下拉列表中選擇GuestResponse。確保選擇母版頁“選項沒有被選中,視圖內容設置為空。單擊“添加”創建新的視圖。MVC創建了一個新的視圖文件,~/Views/Home/Thanks.cshtml.編輯新的視圖,如Listing 3-12。
Listing 3-12. The Thanks View @model PartyInvites.Models.GuestResponse @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Thanks</title> </head> <body> <div> <h1>Thank you, @Model.Name!</h1> @if (Model.WillAttend == true) { @:It's great that you're coming. The drinks are already in the fridge! } else { @:Sorry to hear that you can't make it, but thanks for letting us know. } </div> </body> </html>
Thanks View使用Razor顯示基於GuestResponse類的屬性值的內容,通過RsvpForm的action方法訪問視圖。@model運算符指定View的域模型的是強類型的類型。要訪問域對象的屬性值,我們使用Model.PropertyName。例如,得到的Name屬性的值,我們使用,Model.Name。不要擔心,如果的Razor語法不熟悉 - 我們將在第5章解釋它現在,我們已經創建了Thanks View啟動應用程序Visual Studio中,單擊“RSVP”鏈接,之后添加一些數據,並單擊“SubmitRSVP“按鈕。你會
看到如圖3-17所示的結果(雖然它可能會有所不同,如果你的名字是不是Joe,或者你選擇不能參加)。
添加驗證
現在我們為應用程序添加驗證。如果我們不這樣做,我們的用戶可以輸入垃圾數據,甚至提交一個空的表單。在MVC應用程序中,驗證通常應用在域模型中,而不是在用戶接口。這意味着,我們在同一個地方定義我們的驗證標准,它在任何地方生效。ASP.NET MVC支持聲明System.ComponentModel.DataAnnotations命名空間的屬性定義的驗證規則。
清單3-13顯示了如何將這些特性應用於到的GuestResponse的模型類。
上面用粗體顯示了驗證規則。 MVC檢測驗證屬性,並使用它們來來驗證數據模型的綁定過程。請注意,我們導入了包含驗證類的命名空間。
提示如前所述,我們使用了一個可為空的布爾的WillAttend屬性。所以我們可以應用必要的驗證屬性。如果我們用一個普通的布爾值,該值可能是我們通過模型綁定唯一的true或false的,我們將不用去告訴如果用戶怎么樣選擇一個值。可空布爾有三個可能的值:true,false和null。空值將被使用,如果用戶還沒有選擇的一個值,這所需的屬性來報告驗證錯誤。我們在我們的控制器類可以使用ModelState.IsValid屬性檢查驗證狀態。
清單3-14顯示了如何做到這一點
如果沒有驗證錯誤,我們告訴MVC渲染Thanks視圖。如果有驗證錯誤,我們重新呈現的RsvpForm之前的視圖,並將錯誤顯示給用戶我們需要顯示給用戶,驗證錯誤,我們可以使用Html.ValidationSummary輔助方法,如清單3-15所示。
如果有沒有錯誤,Html.ValidationSummary的方法創建一個隱藏的 MVC的占位符,並添加驗證屬性定義錯誤消息。你可以看到這顯示在圖3-18。
注意:如果您使用過ASP.NET WebForm,你就會知道,“服務器控件,WebForm通過序列化到__VIEWSTATE的隱藏的表單字段的值保持狀態。 ASP.NET MVC模型綁定
不同於WebForm的服務器控件,回發,視圖狀態的概念。 ASP.NET MVC不注入隱藏的__VIEWSTATE字段到您的渲染HTML頁面。
高亮顯示驗證
HTML helper方法是創建文本框,下拉框和其他元素的HTML的輔助方法,它有一個非常方便的功能,可用於與模型綁定。同樣的機制,可以保留的數據表單中輸入的用戶也可以用於突出顯示個別字段失敗驗證檢查。
當一個模型類的屬性未通過驗證,HTML輔助方法會產生輕微不同的HTML。舉個例子,這里的HTML是調用Html.TextBoxFor(X => x.Name的)產生的
如果沒有驗證錯誤將是如下代碼:
<input data-val="true" data-val-required="Please enter your name" id="Name" name="Name" type="text" value="" />
當用戶沒有提供一個值(這是一個驗證錯誤,因為我們調用了GuestResponse模型類Name屬性的Required驗證約束)你會看到代碼略有不同:
<input class="input-validation-error" data-val="true" data-val-required="Please enter your name" id="Name" name="Name" type="text" value="" />
我們加粗以突出顯示的不同之處。這個helper方法添加一個CSS類,稱為input-validation-error。不同的輔助方法適用於不同的CSS類,但它們都可以在~/Content/Site.css的樣式表中找到。怎么引入該樣式表,是這樣的:
<link rel="Stylesheet" href="@Href("~/Content/Site.css")" type="text/css"/>
提示:如果你已經使用了ASPX視圖引擎,您可以使用指定路徑直接使用符號(〜)(如:HREF=“〜/內容/的Site.css的”),並依靠視圖引擎轉換到一個URL,瀏覽器可以按照(如 href="~/Content/Site.css")。 Razor視圖引擎采用不同的方法。它要求使用HREF運算符將URL(如:HREF href="@Href("~/Content/Site.css")")。在第5章中,你可以找到更詳細的介紹。
現在,當用戶提交數據,將導致驗證錯誤,他會看到一個更加明顯方式展示問題的根源,如圖3-19所示。
完成示例
我們的應用程序中的最后一個要求是我們的朋友,使用電子郵件完成給組織者的回函。我們可以通過添加action方法並使用.NET框架中e-mail類來創建和發送電子郵件的信息做到這些,不過這里,我們將使用webmail的輔助方法。這不是MVC框架的一部分,但它確實讓我們完成這個例子中的細節,而不用設立其他的發送電子郵件形式。
請注意 我們使用了webmail的輔助方法,因為它讓我們發送電子郵件消息的變得不費吹灰自理。然而,通常情況下,我們寧願把這個功能的放在一個action方法中。在第4章中描述了MVC架構模式時,我們將解釋為什么。
清單3-16 Using the WebMail Helper
@model PartyInvites.Models.GuestResponse @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Thanks</title> </head> <body> @{ try { WebMail.SmtpServer = "smtp.example.com"; WebMail.SmtpPort = 587; WebMail.EnableSsl = true; WebMail.UserName = "mySmtpUsername"; WebMail.Password = "mySmtpPassword"; WebMail.From = "rsvps@example.com"; WebMail.Send("party-host@example.com", "RSVP Notification", Model.Name + " is " + ((Model.WillAttend ?? false) ? "" : "not") + "attending"); } catch (Exception) { @:<b>Sorry - we couldn't send the email to confirm your RSVP.</b> } } <div> <h1>Thank you, @Model.Name!</h1> @if (Model.WillAttend == true) { @:It's great that you're coming. The drinks are already in the fridge! } else { @:Sorry to hear that you can't make it, but thanks for letting us know. } </div> </body> </html>
我們增加了一個Razor代碼塊,使用WebMail的輔助方法配置電子郵件服務器,包括服務器名稱,服務器是否需要SSL連接,和帳戶詳細信息。
一旦我們配置了所有的細節,我們就可以使用WebMail.Send的方法來發送電子郵件。這里我們使用在try ... catch塊,如果不發送電子郵件不成功也可以提醒用戶。一個更好的方法是如果不能發送的電子郵件消息將顯示一個單獨的錯誤視圖而不是在同一個View中顯示各用戶,但我們希望保持我們的第一個MVC應用程序中的簡單易懂(所以暫時不這么做)。
總結
在本章中,我們創建了一個新的MVC項目,並用它來構建一個簡單的MVC數據輸入應用程序,讓你一睹MVC框架結構和方法的魅力。我們跳過了一些關鍵的功能(包括Razor語法,路由和自動測試),但在后面的章節中,我們會回頭來深入這些主題。在下一章中,我們將探討的MVC架構,設計模式和技術,並貫穿全書。