ASP.NETMVC3 pro系列翻譯


    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.csC#代碼文件打開它進行編輯時,你可以看到,這個被稱為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的童鞋這是一個很好的開端我們創建了一個名為為Indexaction方法,它會返回字符串“Hello,world”再次運行該項目(從Visual Studio的“調試菜單選擇“啟動調試)瀏覽器將顯示的結果。如圖3-6所示

圖3-6 瀏覽器輸出結果

了解路由
  除了模型,視圖和控制器,MVC應用程序也使用ASP.NET路由系統決定如何將URL映射到特定的控制器和action中
  當Visual Studio創建的MVC項目它會添加一些默認路由,您可以使用下面的任何一個URL請求他們將被引導到了HomeControllerIndex action

•  /
•  /Home
•  /Home/Index

瀏覽器請求http://yoursite/http://yoursite/Home,將調用HomeController的Index方法輸出字符串“Helloworld是一個很好的遵循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屬性一個可為空布爾值,這意味着它可能是truefalse,或者為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應用程序,MVCURL對應於物理文件每個action方法都有其自己的URL,MVC使用ASP.NET路由系統把這些urls指向創建的action方法.如果您單擊的鏈接你會看到一個404 Not Found錯誤.因為我們還沒有創建的action方法
對應的/Home/RsvpFormURL為此,我們要給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方法添加的視圖但我們會一些調整,我們要創建一個強類型的視圖一個強類型的視圖的目的是渲染一個特定的域類型,如果我們指定的類型我們使用在這個例子中是GuestResponseMVC可以提供一些有用快捷方式,使其更容易
   注意 做其他事情之前,請確保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項目漂亮。

 處理表單
  我們沒有告訴MVC的形式發送到服務器時,我們想要做的是什么。就目前情況來看,點擊“SubmitRSVP按鈕,會清除任何你輸入到表單中的值。這是因為,表單回發后只是調用了Home controller中的RsvpFrom方法,告訴MVC再次查看視圖.
  注意 輸入的數據再次呈現視圖時丟失你可能會感到失望如果真是這樣,你寧可使用ASP.NET WebForm開發應用程序,因為他有自動保存數據的功能。現在,我們將向您展示MVC如何實現同樣的效果接收和處理提交的表單數據我們要做一個聰明事情我們將再添加一個RsvpForm的action方法
  •響應HTTP GET請求方法GET請求是什么瀏覽器問題通常每次有人點擊一個鏈接這個版本的操作負責顯示初始空白表格,當有人第一次訪問/Home/       RsvpForm
  •響應HTTP POST請求的方法默認情況下,表單呈現Html.BeginForm()方法提交一個POST請求瀏覽器這個版本的action負責接收提交的數據,並決定如何處理。
  將GET和POST請求在單獨的C#方法處理有助於保持我們的代碼整潔,因為這兩個方法有不同的責任。這兩個action方法調用相同的URL,但MVC會調用適當的方法。
清單3-11。增加一個action方法來支持POST請求
 
using System; 
using System.Web.Mvc; 
using PartyInvites.Models; 
 
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(); 
        } 
         [HttpGet] 
        public ViewResult RsvpForm() { 
            return View(); 
        } 
 
        [HttpPost] 
        public ViewResult RsvpForm(GuestResponse guestResponse) { 
            // TODO: Email guestResponse to the part organizer 
            return View("Thanks", guestResponse); 
        } 
    } 
} 
 

    我們已經添加了的HTTPGET特性,RsvpForm的action方法。這是告訴MVC,這種方法只能用於GET請求。然后,我們添加了一個重載的方法RsvpForm,其中需要一個GuestResponse類型的參數用應用HttpPost特性。告訴MVC新的方法將處理POST請求。請注意,我們導入了PartyInvites.Models命名空間。所以下面代碼中無需類的全限定名。

使用模型綁定
  第一個重載的RsvpForm的action方法,使用之前相同的View。它產生的形式如圖3-15所示。第二個重載是更有趣,因為傳入了參數,但考慮到
該action方法將作為HTTP POST請求的響應被調用,但是GuestResponse類型是一個C#類,怎么怎么進行關聯呢?

  答案是綁定Model,這是MVC一個非常有用的功能,即輸入的數據進行解析被用來填充的域模型類型的屬性的鍵/值對。這個過程和使用HTML輔助方法相反的,也就是說,當創建的表單數據發送給客戶端,我們生成的HTML輸入元素的id和name屬性的值來自在模型類的屬性名。與此相反,與模型的結合,輸入元素的名稱是
用於設置模型類的一個實例的屬性值,然后將其傳遞給處理的POST請求的action方法。
  模型綁定是一個強大的和可定制的功能,讓我們不再面的瑣碎的與HTTP請求,而是讓我們的面向C#對象,(不用在處理的Request.Form[]的Request.QueryString[]值。) GuestResponse對象作為參數被傳遞action方法中自動去填充表單字段的數據。在第17章中我們將深入到模型的bind的細節也包括如何自定義。。。

渲染視圖

  第二個重載的在RsvpForm的action方法,還演示了如何響應一個請求,渲染特定視圖。如下面的語句:
  return View("Thanks", guestResponse);

  它通知MVC查找和渲染名為“Thanks”的視圖,並傳入我們的GuestResponse對象。創建的視圖,右鍵單擊里面的其中一個RsvpForm方法,並從彈出的菜單中選擇添加視圖。設置名稱為“Thanks”.

如圖3-16所示。

     我們將創建另外一個強類型的視圖,因此在添加視圖對話框中,我們選擇的視圖模型必須與傳遞給視圖中使用的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.TextBoxForX => 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架構,設計模式技術,並貫穿全書


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM