ASP.NET MVC Music Store教程(3):視圖和視圖模型

來源:互聯網
上載者:User

轉自http://firechun.blog.163.com/blog/static/31804522201102711480936/

到目前為止,我們僅僅從控制器動作返回字串,這是一個瞭解控制器如何工作的好方法,但這並不是你想要的真實的Web應用程式。我們想要一個更好的方法為訪問我們網站的瀏覽器產生HTML,使用模板檔案可以更容易地定製發回的HTML內容。

添加視圖模板

要使用視圖模板,可以修改HomeController的Index方法,讓它返回ActionResult,就象下面這樣返回View():

public class HomeController : Controller 

    // 
    // GET: /Home/ 
    public ActionResult Index() 
    { 
        return View(); 
    } 
}

上述修改標誌著返回的字串被替代,我們使用“View”產生返回結果。

現在為我們的項目添加一個適當的視圖,把游標定位到Index動作方法上,單擊右鍵,選擇“添加視圖”,進入

 

 

 

 “添 加視圖”對話方塊允許我們方便快捷地產生視圖模板檔案。預設情況下,“添加視圖”對話方塊會預先填寫視圖模板的名稱以匹配使用它的動作方法,因為我們在 HomeController的Index動作方法上使用右鍵菜單上的“添加視圖”,因此“添加視圖”對話方塊預設填寫Index作為視圖名稱,我們不需要 改變任何選項,點擊“添加”按紐。

點擊“添加”按紐後,VS在Views\Home目錄中建立了一個新的模板:Index.cshtml,如果目錄不存在,VS會自動建立它。

 

 “Index.cshtm”的檔案名稱和檔案夾非常重要,遵循了ASP.NET MVC約定。\Views\Home匹配HomeController控制器,視圖模板名稱——Index則匹配顯示該視圖的控制器動作方法。

使用ASP.NET MVC命名規範返回視圖,可以讓我們避免顯示指定視圖模板的名稱和位置。當我們在HomeController中編寫如下代碼時,預設情況下將呈現\Views\Home\Index.cshtml視圖模板。

public class HomeController : Controller 

    // 
    // GET: /Home/ 
    public ActionResult Index() 
    { 
        return View(); 
    } 
}

在“添加視圖”對話方塊中按下“添加”按紐後,VS建立並開啟Index.cshtml視圖模板,Index.cshtml的內容如下所示:

@{ 
    ViewBag.Title = "Index"; 

<h2>Index</h2>

視 圖使用了Razor,一種比ASP.NET及較早版本的ASP.NET MVC使用的Web Forms引擎更簡潔的文法。ASP.NET MVC 3仍然支援Web Forms視圖引擎,但大多數開發人員認為Razor視圖引擎比它更適合ASP.NET MVC 的開發。

首三行用ViewBag.Title設定頁面標題,我們很快會看到它是如何工作的更多細節,但現在先讓我們更改視圖頁面的文本,把<h2>標籤中的內容改成如下所示:

<h2>This is the Home Page</h2>

運行程式,在首頁中我們可以看到新的文本:

大多數網站在多個頁面之間有相同的內容:導覽列、腳註、Logo圖片、樣式引用等等,Razor視圖引擎自動在/Views/Shared 檔案夾下建立的_Layout.cshtml使我們更容易管理。

 雙擊這個檔案,內容如下:

<!DOCTYPE html> 
<html> 
<head> 
    <title>@ViewBag.Title</title> 
    <link href="@Url.Content("/Content/Site.css")" 
rel="stylesheet" type="text/css" /> 
    <script src="@Url.Content("/Scripts/jquery-1.4.4.min.js")" 
type="text/javascript"></script> 
</head> 
<body> 
    @RenderBody() 
</body> 
</html>每個視圖自己的內容由@RenderBody()命令顯示,除此之外的任何共用的內容都可以添加到_Layout.cshtml中。我們希望網站的所有頁面都有一個連結到Home和Store的頭部,直接在@RenderBody()前面添加這些代碼即可。<!DOCTYPE html> 
<html> 
<head> 
    <title>@ViewBag.Title</title> 
    <link href="@Url.Content("/Content/Site.css")" 
rel="stylesheet" type="text/css" /> 
    <script src="@Url.Content("/Scripts/jquery-1.4.4.min.js")" 
type="text/javascript"></script> 
</head> 
<body> 
    <div id="header"> 
        <h1> 
            ASP.NET MVC MUSIC STORE</h1> 
        <ul id="navlist"> 
            <li class="first"><a href="/" id="current">Home</a></li> 
            <li><a href="/Store/">Store</a></li> 
        </ul> 
    </div> 
    @RenderBody() 
</body> 
</html>(引用樣式的說明略,從http://mvcmusicstore.codeplex.com下載原始碼,所有圖片和樣式指令碼、資料庫都在MvcMusicStore-Assets目錄中) 運行應用程式,新的首頁是下面的樣子:

 讓我們看看做了哪些修改:

  • 因為視圖模板遵循標準命名規範,HomeController的Index動作方法通過調用“return View()”找到並且顯示\Views\Home\Index.aspx視圖模板。
  • 通過在\Views\Home\Index.aspx中的定義,首頁顯示了一條簡單的歡迎資訊。
  • 使用主版頁面,歡迎資訊呈現出標準的HTML布局。

使用模型(Model)把資訊傳遞給視圖

視圖模板僅僅顯示硬式編碼HTML內容不足以構建一個令人感興趣的網站,要建立動態網站,我們應該從控制器動作中傳遞資訊到視圖模板。

在Model-View-Controller(模型-視圖-控制器)模式中,模型是對應用程式要呈現的資料的對象引用,通常來說,模型對象相當於資料庫中的表,但這裡不是。

返回ActionResult的控制器動作方法可以把模型對象傳遞給視圖,這使得控制器乾淨地封裝了所有需要的資訊產生一個響應,把這些資訊傳遞給視圖模板並產生適當的HTML響應。在控制器動作中看它是最容易理解的,那麼讓我們開始吧。

首先,我們建立一些模型類來描述音樂倉庫的類別和唱片,讓我們從建立Genre類開始。在你的項目中,按右鍵“Models”檔案夾,選擇“添加->類”,並將檔案命名為Genre.cs

 在建立的類中增加一個公用的字串屬性——Name

public class Genre 

    public string Name { get; set; } 
}

注意:這裡你可能會感到奇怪, { get; set; } 是C#自動屬性(C#3.0支援)這讓我們方便定義屬性而不需要聲明欄位。

下面,按相同的步驟添加唱片類(Album.cs),它有兩個屬性:Title和Genre

 public class Album 

    public string Title { get; set; } 
    public Genre Genre { get; set; } 
}

現在,我們可以修改StoreController,使用視圖顯示模型資訊:

 我 們修改StoreController中的Details動作,讓它顯示單個唱片的資訊。在StoreController類的頂部增加using語句以 包含MvcMusicStore.Models命名空間,這樣,我們每次使用Album類時,不需要輸入 MvcMusicStore.Models.Album ,using部分看起來如下所示:

using System; 
 using System.Collections.Generic; 
 using System.Linq; 
 using System.Web; 
 using System.Web.Mvc; 
 using MvcMusicStore.Models; 
 下面,我們修改Details控制器動作,讓它返回ActionResult而不是字串,我們曾經對HomeController的Index方法做過同樣的修改。

public ActionResult Details(int id)

現在我們修改商務邏輯為視圖返回一個Album對象,在本教程的最後,我們會從資料庫接收資料,但現在,讓我們先從“類比資料”開始吧。

public ActionResult Details(int id) 
 { 
    var album = new Album { Title = "Album " + id }; 
    return View(album); 
 }

(對var類型變數的解釋,不寫了)

現在可以建立使用Album產生HTML響應的視圖模板,在此之前我們需要產生項目以便讓“添加視圖”對話方塊知道我們建立的Album類,在“產生”菜單中選擇“產生MvcMusicStore”。

 設 置好支援的類後,我們準備建立視圖模板,在Details方法上單擊右鍵並在捷徑功能表上選擇“添加視圖”,就象之前為HomeController建立視 圖模板一樣,由於我們從StoreController中建立,預設會產生 檔案\Views\Store\Details.aspx。

和之前不同的是,這次我們把“建立強型別視圖”勾選上,然後在“視圖資料類”下拉框中選擇Album類,“添加視圖”對話方塊將產生視圖模板,並將Album對象傳遞給它。

 (以下和原文不同,微軟更新太快,原文已經使用MVC 3,因為時間關係,目前我還不打算在我們的項目中使用MVC 3 的Razor文法,因此下面全部使用MVC 2完成,功能和原文保持一致)

Details.aspx的頁面指令中包含以下代碼:

Inherits="System.Web.Mvc.ViewPage<MvcMusicStore.Models.Album>"

表示這是個Album的強型別視圖,可以讓我們更容易訪問模型的屬性,並受VS的“智能感應器”的支援。

在<h2>標籤中顯示Album的Title屬性:

    <h2>Album:<%:Model.Title %></h2>
注意當我們輸入<%:之後,VS的智能感應器會顯示,Model是預設的Album對象名稱,並且可以在智能感應器中看到相關的屬性和方法。

(註:<%: %>是ASP.NET 4的新文法,等效於<%=Server.HtmlEncode()%>)

運行應用程式並訪問URL /Store/Details/5,我們看到了唱片的詳細資料:

 現在我們同樣更新StoreController的Browse動作方法,修改方法的傳回值為ActionResult,修改方法的商務邏輯返回一個Gener對象給視圖。

public ActionResult Browse(string genre) 
 { 
    var genreModel = new Genre { Name = genre }; 
    return View(genreModel); 
 }

在Browse方法上單擊右鍵選擇“添加視圖”,添加一個Genre的強型別視圖。

 更新視圖代碼:

<h2>Browsing Genre:<%:Model.Name %></h2>

運行應用程式並訪問URL /Store/Browse?Genre=Disco,我們看到如下的瀏覽頁面:

 最後,讓我們做一個稍微複雜點的修改:讓StoreController的Index動作方法和視圖顯示倉庫中所有類別的列表,我們使用Genre的集合而不是單個Genre對象。

public ActionResult Index() 

    var genres = new List<Genre> 
    { 
        new Genre { Name = "Disco"}, 
        new Genre { Name = "Jazz"}, 
        new Genre { Name = "Rock"} 
    }; 
    return View(genres); 
 }

在Index方法上單擊右鍵選擇“添加視圖”,類型選擇Genre,視圖內容選擇“List”:

 注意Index.aspx的Page指令部分和之前不同,如果在剛才的“添加視圖”裡沒有把“視圖內容”選擇為“List”,也可修改成如下所示:

Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcMusicStore.Models.Genre>>"把代碼改成如下所示:    <h3>
        Browse Genres</h3>
    <p>
        Select from <%:Model.Count()%> genres:</p>
    <ul>
        <%foreach (var genre in Model){%>
        <li>
            <%:genre.Name%></li>
        <%} %>
    </ul>(本人註:對照一下原文使用的MVC 3的Razor文法,可以體會出Razor文法的優勢)注意原來產生的程式碼為列表的每一項都產生了Edit,Details和Delete連結,不過我們在稍後的倉庫管理中再應用這些功能,因此我們用上面較簡單的代碼替換了自動產生的程式碼。運行程式,瀏覽/Store,我們可以看到類別的數量和列表都顯示出來。

 添加頁面之間的連結/Store URL把當前類別的名稱作為純文字列出,現在讓我們用一個指向/Store/Browse URL的連結來替換這些純文字,當我們在類別名稱——比如“Disco”上點擊時可以被導航到/Store/Browse?genre=Disco URL,更新\Views\Store\Index.aspx視圖模板,修改成如下代碼:        <%foreach (var genre in Model){%>
        <li>
            <a href="/Store/Browse?genre=<%:genre.Name%>"><%:genre.Name%></a></li>
        <%} %>
運行沒問題,不過使用寫入程式碼可能會為我們帶來麻煩,例如,如果我們想重新命名控制器,我們必須搜尋代碼中所有連結到該控制器的地方並進行修改。一 個可供選擇的方式是,我們可以利用HTML helper中的方法。ASP.NET MVC中包含的HTML helper方法允許我們從視圖模板中執行象這種要求的各種通用任務。Html.ActionLink() helper方法就是特別有用的方法之一,它可以輕鬆地協助我們構建HTML <a>標籤,並且處理那些令人厭煩的細節——比如確定URL路徑是否經過恰當的URL編碼(Encode)。Html.ActionLink() 有好幾個重載,允許我們為連結指定所需的資訊,在我們這個簡單的例子中,我們只需提供連結文本和超連結被點擊時指向的動作方法。例如,我們使用下列代碼在 /Store/Details.aspx中建立一個指向StoreController中的Index方法的連結:<%:Html.ActionLink("Go to the Store Index", "Index")%>

注意:在上面的例子中,因為是從當前視圖連結到同一個控制器的另一個動作,所以不需要指定控制器的名稱。

連結到Browse頁面需要傳遞一個參數,這裡我們用Html.ActionLink()有三個參數的重載:

  • 1.連結的文本——使用類型名稱(genre.Name)
  • 2.控制器動作名稱——Browse
  • 3.路由參數——需要指定參數名稱和值,參數名稱是genre,值是genre.Name

新的代碼:

        <%foreach (var genre in Model){%>
        <li>
            <%:Html.ActionLink(genre.Name,"Browse",new {genre=genre.Name}) %>
        </li>
        <%} %>

現在運行我們的項目並訪問 /Store/ URL,我們可以看到類別列表,每個類別都是一個超連結,點擊後會把我們帶到/Store/Browse?genre=[genre] URL。

網頁產生的HTML代碼看起來如下所示:

<ul> 
    <li><a href="/Store/Browse?genre=Rock">Rock</a> 
</li> 
    <li><a href="/Store/Browse?genre=Jazz">Jazz</a> 
</li> 
    <li><a href="/Store/Browse?genre=Country">Country</a> 
</li> 
    <li><a href="/Store/Browse?genre=Pop">Pop</a> </li> 
    <li><a href="/Store/Browse?genre=Disco">Disco</a> 
</li> 
</ul>

(本人註:關於Html.ActionLink()的用途和好處,可以參看我的另一篇文章:布署ASP.Net MVC應用程式時的連結地址問題)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.