跟小靜學MVC3[02]--從注冊模塊實戰MVC新特性


上一節我們創建了自己的第一個MVC3項目,並了解了Controller和View的添加方法。今天我們將仿照大米返利網注冊模塊寫個小例子,來進一步了解Model、Action、Form等相關內容。

情景假設

  • 首頁--歡迎頁面,簡單介紹大米返利網,並提供注冊鏈接;
  • 注冊--用戶使用網站之前要先注冊為會員,注冊頁面還要對用戶填寫的信息進行有效性驗證;

          image

  • 注冊完成--完成之后會跳轉到一個提示頁面,並向用戶郵箱發送一封郵件。

一. 首頁

1. 將上一節的Index頁面用作首頁,再添加一些說明文字。

首頁 View代碼
@{
    ViewBag.Title = "首頁";
}
< h2 >@ViewBag.hello </ h2 >
< p >大米返利網提供淘寶網等多家商城的返現優惠, < br />
    返現比例高,提現速度快,注冊贈1元,滿3元提現。 </ p >
< p >點此注冊 </ p >

 

image

接下來我們就要為“點此注冊”提供鏈接頁面了。

二. 添加注冊頁面

1. 創建數據Model

MVC中的M代表的領域模型,是應用程序中極其重要的部分之一,一個設計完好的MVC項目往往從設計完好的model開始,然后在此基礎上繼續添加controller和view。在我們的項目中,model是對現實世界對象的封裝,定義規則、處理等等。具體實現時Model一般就是對項目中通用性對象的屬性、方法進行封裝而來的C#類,然后controller和view以一定的方式暴露給客戶端。

接下來我們添加一個用戶信息的model類:右鍵models文件夾->Add->Class->UserInfo.cs->Ok.

UserInfo.cs Code
///   <summary>
    
///  注冊用戶實體
    
///   </summary>
     public  class UserInfo
    {
         ///   <summary>
        
///  自動編號
        
///   </summary>
         public  int Id {  getset; }

         ///   <summary>
        
///  用戶名
        
///   </summary>
         public  string UserName {  getset; }

         ///   <summary>
        
///  密碼(明文簡單示例)
        
///   </summary>
         public  string Password {  getset; }

         ///   <summary>
        
///  qq號碼
        
///   </summary>
         public  string QQ {  getset; }

         ///   <summary>
        
///  郵箱地址
        
///   </summary>
         public  string Email {  getset; }
    }

2. 添加Action

在IndexController中添加新的action:

        // 注冊
         public ActionResult Register()
        {
             return View();
        }

3. 添加強類型View

  • 創建view:強類型view目的是展現針對具體類型的實體,指定具體類型之后MVC會為其提供許多快捷的操作。需要注意的是,在添加強類型View之前,我們要先編譯整個MVC項目,否則添加View時就會找不到先前添加的UserInfo實體。

添加步驟:

在Register Action代碼塊內右鍵->Add View->選中 Create a strongly type view復選框->Model class下拉框選擇UserInfo->提供的模板選擇Empty->Add。如下圖所示:

image

添加完成之后我們發現新添加的View是以@model的Razor代碼開頭的。接下來我們將會看到,這正式強類型view以及它能提供諸多便捷的關鍵所在。

三、編輯表單

1. View代碼

< h1 >大米返利網 </ h1 >
@using(Html.BeginForm())
{
     < p >用戶名: @Html.TextBoxFor(m=>m.UserName) </ p >
     < p >密碼:@Html.PasswordFor(m=>m.Password) </ p >
     < p >確認密碼:@Html.PasswordFor(m=>m.Password) </ p >
     < p >QQ:@Html.TextBoxFor(m=>m.QQ) </ p >
     < p >Email:@Html.TextBoxFor(m=>m.Email) </ p >
     < input  type ="submit"  value ="馬上注冊" />
}

 

這里用的是Razor語法,使用過程中VS為我們提供了豐富的智能感知。以前不熟悉的同學可能會看着滿眼的@符號不太自在,用一段時間就該上癮了,因為它真的很好上手。運行效果如下:

image

2. Html幾個helper方法:

首先,我們看一下頁面源代碼:


頁面源代碼
< h1 >大米返利網 </ h1 >

< form  action ="/index/register"  method ="post" >

< p >用戶名: < input  id ="UserName"  name ="UserName"  type ="text"  value =""   /></ p >

< p >密碼: < input  id ="Password"  name ="Password"  type ="password"   /></ p >

< p >確認密碼: < input  id ="Password"  name ="Password"  type ="password"   /></ p >

< p >QQ: < input  id ="QQ"  name ="QQ"  type ="text"  value =""   /></ p >

< p >Email: < input  id ="Email"  name ="Email"  type ="text"  value =""   /></ p >

< input  type ="submit"  value ="馬上注冊" />

</ form > 
  • 不難看出,通過Razor語法中的Html helper方法,將Model中的屬性用Input控件形式展現出來了。例如
@Html.TextBoxFor(m=>m.UserName)

生成html時,input控件type=”text”, id和name屬性都被賦值為"UserName“。對應html代碼為:

< input  id ="UserName"  name ="UserName"  type ="text"  value =""   />
  • 對於強類型view,書寫lamda語法時有着豐富的智能感知。如果不想寫成lamda形式,還可以這樣 @Html.TextBoxFor(“UserName”)
  • Html.BeginForm:

代碼格式為@using(Html.BeginForm()){   …},通常使用using關鍵字是為了走出花括號時釋放較占資源的對象,而在這里可以理解為關閉<form>標簽。生成form屬性時,默認的action會提交回當前的url,而method默認設置為post。最終生成的html源碼為:<form action="/index/register" method="post"> ……</form>。

另外,在WebForm開發時,每個頁面只允許使用一個服務端form,並且包含ViewState以及postback邏輯,而在MVC中是沒有服務器端form這個概念的,沒有ViewState以及postback機制,每個頁面可以放置多個form。

  • Html.ActionLink:用來添加action頁面的鏈接,我們可以在首頁為“點此注冊”添加鏈接:
@Html.ActionLink("點此注冊","Register","Index")

四. 表單提交

  1.  HttpGet和HttpPost:

為了接收並處理提交的表單數據,我們還需要再添加一個Register action,這兩個action的作用是:

  • 一個用來響應Http Get請求: 為action添加HttpGet特性(也可以省略),Get請求通常是用戶第一次訪問頁面時,通過該action初始化空白表單。
  • 一個用來響應Http Post請求:為acton方法添加HttpPost特性,Html.BeginForm()創建的窗體默認被瀏覽器處理為Post請求。這個版本的action方法負責接收提交的表單數據並進行相應處理。
       [HttpGet]
        public ActionResult Register()
        {
            return View();
        }
         [HttpPost]
        public ActionResult Register(UserInfo userInfo)
        {
            return View("Complete",userInfo);
        }

2.Model Binding

在上面的post方法中,使用了MVC中一個非常不錯的特性---Model Binding,它可以解析傳來的數據並將其對應到領域模型的屬性。其實這個Model Binding過程是雙向的,當創建form數據時,input控件的值是根據與其name對應的model屬性來賦值的;反過來,當提交form表單時,通過model binding又可以根據input控件的name屬性來為model實體同名的屬性賦值,進而提交到post action方法。

五、表單驗證

在MVC應用程序中,我們一般把驗證添加在model實體而不放在用戶界面,這樣只要我們在一處定義了驗證規則便可以多處生效。ASP.NET MVC總具體實現方式是:使用System.ComponentModel.DataAnnotations 中定義的特性,將其聲明在model屬性作為驗證規則就可以生效了。

1. Model實體添加驗證規則

Model Validation Code
using System.ComponentModel.DataAnnotations;
namespace DamifanliMvc3.Models
{
     ///   <summary>
    
///  注冊用戶實體
    
///   </summary>
     public  class UserInfo
    {
         ///   <summary>
        
///  自動編號
        
///   </summary>
         public  int Id {  getset; }

         ///   <summary>
        
///  用戶名
        
///   </summary>
        [Required(ErrorMessage =  " 請輸入用戶名 ")]
       [RegularExpression( " ^[a-zA-Z][a-zA-Z0-9]{2,14}$ ", ErrorMessage =  " 請輸入3-15位字母或數字 ")]
         public  string UserName {  getset; }

         ///   <summary>
        
///  密碼(明文簡單示例)
        
///   </summary>
        [Required(ErrorMessage =  " 請輸入密碼 ")]
         public  string Password {  getset; }

         ///   <summary>
        
///  qq號碼
        
///   </summary>
        [Required(ErrorMessage =  " 請輸入QQ號碼 ")]
        [RegularExpression( " [1-9][0-9]{4,} ",ErrorMessage =  " 請輸入正確的qq號碼 ")]
         public  string QQ {  getset; }

         ///   <summary>
        
///  郵箱地址
        
///   </summary>
        [Required(ErrorMessage =  " 請輸入郵箱地址 ")]
        [RegularExpression( @" \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* ",ErrorMessage =  " 請輸入正確的郵箱地址 ")]
         public  string Email {  getset; }
    }
}

2.ModelState.IsValid

我們可以在Controller中使用ModelState.IsValid來檢驗是否存在驗證問題。

public ActionResult Register(UserInfo userInfo)
        {
             if ( ModelState.IsValid)
            {
                 return View( " Complete ", userInfo);    // Complete Action后續創建
            }
             return View();
        }

3.錯誤提示

當用戶輸入不符合規則時,我們可以在view中使用Html.ValidationSummary()來提示用戶。

@using(Html.BeginForm())
{
@Html.ValidationSummary()
    <p>用戶名:@Html.TextBoxFor(m=>m.UserName)</p>
    ……

}

該方法會在頁面中放置一系列隱藏的li,MVC可以令這些位置可見並顯示model驗證屬性中定義的錯誤信息,如下圖所示。點擊注冊按鈕時該頁面不會進行跳轉,直到所有輸入都符合規范為止。值得慶幸的是,提交失敗時之前填寫的數據仍然會保留在頁面中。

image

 

查看頁面源代碼:

< p >
用戶名: < input  class ="input-validation-error"  data-val ="true"  data-val-regex ="請輸入3-15位字母或數字"  data-val-regex-pattern ="^[a-zA-Z][a-zA-Z0-9]{2,14}$"  data-val-required ="請輸入用戶名"  id ="UserName"  name ="UserName"  type ="text"  value =""   />
</ p >

六、注冊完成頁面

1.添加Complete View:

在前面的post提交的Register中,我們已經給出了注冊完成時要跳轉的目標”Complete”,並且傳遞了變量userInfo,接下來我們添加一個強類型UserInfo類型的View。

image

修改代碼如下:

@model DamifanliMvc3.Models.UserInfo
@{
    ViewBag.Title = "注冊完成";
}
< h2 >注冊完成 </ h2 >
< p >
    恭喜,您已注冊成功,請妥善保管注冊信息: < br />
    賬號:@Model.UserName < br />
    QQ:@Model.QQ < br />
    Email:@Model.Email < br />
    大米返利網祝您購物愉快!
</ p >

 

2. 發送郵件通知


在展示Complete View的同時,我們使用WebMail類來發送通知郵件。

@{
    try
    {
        WebMail.SmtpServer = "smtp.sina.com";
        WebMail.SmtpPort = 587;
        WebMail.EnableSsl = true;
        WebMail.UserName = "CathyChen";
        WebMail.Password = "damifanli";
        WebMail.From = "cathychen@sina.com";
        WebMail.Send(@Model.Email,"成功注冊大米返利網",@Model.UserName+",您已成功注冊大米返利網,祝您購物愉快!");
    }
    catch
    {
        @:抱歉,通知郵件發送失敗!
    }
}

小結:

到這里,今天的學習基本結束了。當然了這只是一個簡單的示例,實際使用中還有很多可以改進的地方,比如將發送郵件功能放在單獨的模塊中調用而不是將代碼塊嵌在View中,以便重復使用;另外,這里的錯誤處理使用的try…catch,其實可以跳轉到單獨的錯誤頁面。


免責聲明!

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



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