上一篇中使用字符串,这一篇我们就开始使用视图来处理。

我们已经可以从控制器的 Action 中返回一个字符串,这可以帮助我们更好地理解 Controller 是如何工作的。但是对于创建一个 Web 程序来说还是不够的。下面我们使用更好的方法来生成 HTML,主要是通过模板来生成需要的 HTML,这就是视图所要做的。

增加视图模板

为了使用视图模板,我们需要将HomeController 中的 Index 这个 Action 的返回类型修改为 ActionResult,然后,让它像下面一样返回一个视图。

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

上面的修改表示我们将使用视图来替换掉原来的字符串,以便生成返回的结果。

现在为我们的项目增加一个视图,为达到这个目的,我们将光标移到 Index 方法内,然后,点击鼠标的右键,在右键菜单中选择“添加视图(D)…”,这样将会弹出增加视图的对话框。

添加视图的对话框允许我们快速,简单地创建一个视图模板,默认情况下,视图的名称使用当前 Action 的名字。因为我们是在 Index 这个 Aciton 上添加模板,所以添加视图对话框中,视图的名字就是 Index,我们不需要修改这个名字,点击添加。

在点击添加之后,Visual Studio 将会创建一个名为 Index.cshtml的视图模板,放置在 \Views\Home 目录中,如果没有这个目录,MVC 将会自动创建它。

Index.cshtml 所在文件夹的名称和位置是很重要的,它是根据ASP.NET MVC 的约定来指定的。目录名称 \Views\Home ,匹配的控制器就是 HomeController ,视图模板的名字 Index,匹配将要使用这个视图的 Action 方法的名字。

当使用默认的约定的时候,ASP.NET MVC 允许我们不用显式设置这些名字和位置,当我们的代码如下所示的时候,将会默认寻找 \Views\Home\Index.cshtml。

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

Visutal Studio 创建并打开了Index.cshtml 视图模板,其中的内容如下:

@{  
ViewBag.Title = "Index";
} <h2>Index</h2>

视图使用了 Razor 语法,这比 Web Form 视图引擎的语法更加简单。

前三行使用 ViewBag.Title 设置了页面的标题,我们马上就可以看到这样做的效果,但是,首先,我们我们替换一下网页的内容,将 <h1> 标记中的内容修改为 This is the Home Page 。

@{  
ViewBag.Title = "Index";
} <h2>This is the Home Page</h2>

现在,我们的首页应该变成下面的样子。

为页面的公共内容使用布局

大多数的网站在页面之间有许多共享的内容:导航,页首,页脚,公司的 Logo,样式表等等。Razor 引擎默认使用名为 _Layout.cshtml 的布局来自动化管理,它保存在 /Views/Shared 文件夹中。

打开之后,可以看到下列内容:

<!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 中,我们希望我们的 MVC 音乐商店有一个公共的页首,其中含有链接到我们的首页和商店区域的链接,所以,我们将这些内容直接添加到这个布局中。

<!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>

更新样式表

在创建项目使用的空项目模板中,仅仅包含很简单的用来显示验证信息的样式。我们的设计师提供了一些额外的 CSS 样式和图片来改进网站的观感,现在我们就使用它们。

首先,到网站 mvcmusicstore.codeplex.com 下载 MvcMusicStore-v3.0.zip,这里面有一个文件夹 MvcMusicStore-Assets,将这个文件夹的Content 文件夹的内容复制到项目的 Content 文件夹中。

你会被询问是否需要覆盖存在的文件,选择是。

现在,网站的 Content 文件夹中的内容如下所示:

重新运行程序,现在的页面变成了这样。

我们回顾一下,什么发生了变化:HomeController 的 Index 的 Action 方法寻找并通过 \Views\Home\Index.cshtml 模板生成输出结果,代码中是通过 return View() 实现的,因为默认的命名约定,Index 这个 Action 方法将会默认使用 Index 视图输出。

而 Index 视图使用了我们的 _Layout.cshtml 模板,所以,欢迎信息被包含在标准的 HTML 布局中。

使用模型为视图传递信息

仅仅使用硬编码的 HTML 不能创建令人感兴趣的网站,创建动态网站,我们需要从控制器的 Action 传送信息给视图模板。

在 MVC 模式中,术语 Model 表示应用表现的数据,通常,模型对象用来表示数据库中保存在表中的数据,也不一定如此。

控制器的 Action 方法通过返回的 ActionResule 可以传送模型对象给视图。这就允许控制器可以将所有生成回应需要的数据打包,然会传送给视图模板,以便生成适当的 HTML 回应,在 Action 方法中可以很容易理解,让我们开始吧。

首先,我们将创建一些模型类来表示商店中的唱片类型和专辑类型,从创建类型 Genre 类开始,在项目中,右击模型 Models 文件夹,然后选择增加类选项,然后命名为 Genre.cs。

在新创建的类中增加一个属性。

public class Genre  
{
public string Name { get; set; }
}

注意:这里的 { get; set; } 是 C# 的自动属性特性,这使得我们不需要在创建属性的时候,先创建一个成员字段

现在,用同样的方法创建专辑类 Album,它有两个属性:Title 和 Genre .

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

现在,我们修改 StoreController 通过模型来使视图显示动态信息,为了演示方便,我们定义专辑基于一个唯一的标识 Id, 我们将在视图中显示这个标识。

我们从修改 Details 这个 Action 使得可以显示单个的专辑开始,在 StoreController.cs 的开始部分增加一些 using 语句来包含 MvcMusicStore.Models 命名空间,这使得我们不用总是输入这个命名空间。

using System;  
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; using MvcMusicStore.Models;

然后,我们更新 Details Action ,使得返回 ActionResult 类型的结果而不是字符串,就像在 HomeController 中的 Index 方法中做得一样。

public ActionResult Details(int id)  

现在,修改方法的处理逻辑,返回一个专辑对象到视图中,在这个项目最后,显示的数据将会来自数据库,现在我们仅仅填充一些数据而已。

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

如果你对 c# 不太熟悉,可能你会认为使用 var 定义变量使用了迟绑定,这是不正确的,C# 编译器使用赋予变量的值来推定变量的类型,所以,实际上变量的类型就是 Album 类型,因此不仅在编译时, Visual Studio 的代码编辑器中也会有类型支持。

下面创建一个使用专辑来生成 HTML 的模板,在这样做之前,我们需要编译项目,以便增加视图的对话框知道我们新创建的专辑类型。你可以通过菜单“生成”的“生成解决方案”来完成。

另外,也可以通过热键 Ctrl – Shift – B 来编译项目。

已经可以创建视图模板了,在 Details 方法中右键选择“增加视图…”

像以前一样,我们看到创建视图的对话框,不一样的是,我们要选中“创建强类型视图”,然后在下面的列表中选择“Album”类,这样视图将会期望得到一个 Album 类型的对象。

在点击增加之后,我们的视图模板 \Views\Store\Details.cshtml 被创建了,其中包含的如下的代码:

@model MvcMusicStore.Models.Album  

@{  
ViewBag.Title = "Details";
} <h2>Details</h2>

注意第一行,表示视图使用强类型的 Album 类。Rozer 视图引擎理解传送来的 Album 对象,所以我们可以容易地访问模型的属性,在 Visual Studio 中得到智能感知的帮助。

更新 <h2> 标记,使得可以显示专辑的 Title 属性

@model MvcMusicStore.Models.Album  

@{  
ViewBag.Title = "Details";
} <h2>Album: @Model.Title</h2>

注意,智能感知使得可以提示 Album 的属性和方法。

再次运行并访问 /Store/Details/5,可以得到下面的结果。

现在,我们继续修改 Browse 方法,更新方法返回 ActionResult 类型的结果,修改方法的处理,返回一个 Genre 类型的对象实例。

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

在方法上右击,选择“增加视图…”,增加一个强类型的视图。

修改 <h2> 标记显示 Genre 的信息

@model MvcMusicStore.Models.Genre  
@{
ViewBag.Title = "Browse";
} <h2>Browsing Genre: @Model.Name</h2>

重新运行,访问 /Store/Browse?Genre=Disco,可以看到如下的显示

最后,将 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);
}

创建一个强类型的视图

首先,我们将期望得到多个 Genre 对象而不是一个,将第一行修改为如下内容。

@model IEnumerable<MvcMusicStore.Models.Genre>  

这告诉视图引擎模式是一个包含多个 Genre 对象的集合,我们使用 IEnumerable<Genre> 而不是 List<Genre>,因为这样更通用,可以允许我们在以后改变集合为任何实现 IEnumerable 接口的集合。

现在,我们遍历集合中的 Genre 对象进行处理。

@model IEnumerable<MvcMusicStore.Models.Genre>  
@{
ViewBag.Title = "Store";
}
<h3>
Browse Genres</h3>
<p>
Select from @Model.Count() genres:</p>
<ul>
@foreach (var genre in Model)
{ <li>@genre.Name</li>
}
</ul>

注意,此时有完全的智能提示

在 foreach 循环中,也同样有提示。

再次运行程序,我们可以看到如下的结果。

增加页面之间的链接

现在,我们的 /Store 可以使用纯文本列出当前的分类名称,下一步,我们将这些纯文本替换成可以链接到浏览分类的链接 /Store/Browse 上,这样,当用户点击音乐分类“Disco”将会被导航到 /Store/Browse?genre=Disco 的 URL 地址上。我们再次更新\Views\Store\index.cshtml 视图模板,先看一下,一会我们还会再次改进。

<ul>  
@foreach (var genre in Model)
{
<li><a href=/Store/Browse?genre=@genre.Name>@genre.Name</a></li>
}
</ul>

这样就可以工作了,但是这里使用了硬编码的字符串,如果我们希望修改控制器的名称,那么,我们就要找到所有这样的位置进行修改

更好的处理方式是使用 HTMLHelper 的助手方法,ASP.NET MVC 包含了一个 HTML 的助手类,其中的方法专门用于在视图模板中完成多种常见的任务,其中的Html.ActionLink() 助手方法就是常用的一个,这使得可以容易地创建 <a> ,包括关于链接的一些细节处理,像地址需要进行 URL 编码之类。

Html.ActionLink() 有多个重载用于多种情况,在简单的情况下,你只需要提供提示的文本,以及指向的 Action 方法即可,在客户端,举个例子,我们希望链接到 /Store 的 Index 方法,提示文本为 Go to the Store Index,那么下面的代码就可以。

@Html.ActionLink("Go to the Store Index", "Index")

注意:在这个例子中,我们不需要再特别指定控制器的名称,因为我们在使用同一个控制器的不同 Action 方法。

我们的链接还需要一些参数,我们可以使用另外一种重载来传递三个参数。

1.        链接的提示文本,这里显示分类的名称

2.        控制器的名称,Browse

3.        路由参数,提供名字 genre 和值,genre 的名字

合在一起,下面就是需要写在视图模板中的内容

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

现在,当我们运行程序,访问 /Store 的时候,将会看到一个分类的列表,每一个分类都是一个超级链接,当点击链接的时候,将会被导航到 /Store/Browse?genre=[genre] 的地址

页面中生成的分类链接如下:

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

ASP.NET MVC 音乐商店 - 3. 视图与模型的更多相关文章

  1. ASP.NET MVC 音乐商店 - 目录

    这一个系列的内容来自微软的音乐商店 Music Store, 这是项目在 Codeplex 上的地址:http://mvcmusicstore.codeplex.com/. 这个项目使用 ASP.NE ...

  2. ASP.NET MVC 音乐商店 - 0 概览

    这是一个系列文章,原文内容出自微软的 MusicStore. 首先对原文内容进行了简单的翻译,以方便大家参考,另外对于其中的部分内容,也进行了简单的分析,使用的 Visual Studio 也换成了中 ...

  3. ASP.NET MVC 音乐商店 - 5 通过支架创建编辑表单 续

    查看 StoreManager 控制器的代码 现在,Store Manager 控制器中已经包含了一定数量的代码,我们从头到尾重新过一下. 首先,在控制器中包含了标准的 MVC 控制器的代码,为了使用 ...

  4. ASP.NET MVC 音乐商店 - 5. 通过支架创建编辑表单

    在上一章,我们已经从数据库获取数据,然后显示出来,这一章,我们将允许编辑数据. 创建 StoreManagerController 控制器 我们将要创建称为 StoreManager 的控制器,对于这 ...

  5. ASP.NET MVC 音乐商店 - 2.控制器

    在典型的 Web 应用中,用户请求的 URL 地址通常映射到保存在网站中的文件上,例如,当用户请求 /Products.aspx 的时候,或者 /Products.php 的时候,很可能是在通过处理 ...

  6. ASP.NET MVC 音乐商店 - 1 创建项目

    我们的项目从在 Visual Studio 中的文件菜单中选择“新建”,选择“项目”开始. 然后,选择 C# 中的 Web 模板组,在右边的项目模板中选择 ASP.NET MVC3 Web 应用程序, ...

  7. ASP.NET MVC 音乐商店 - 6. 使用 DataAnnotations 进行模型验证

    在前面的创建专辑与编辑专辑的表单中存在一个问题:我们没有进行任何验证.字段的内容可以不输入,或者在价格的字段中输入一些字符,在执行程序的时候,这些错误会导致数据库保存过程中出现错误,我们将会看到来自数 ...

  8. ASP.NET MVC 音乐商店 - 4. 数据访问

    上一次,我们使用了模拟的数据从控制器发送到视图模板.现在,我们开始使用真正的数据库,在这个教程中,我们将指导如何使用 SQL Server Compact 版的数据库,它经常被称为 SQL CE, 来 ...

  9. MVC 音乐商店 第 8 部分: 购物车与 Ajax 更新

    MVC 音乐商店是介绍,并分步说明了如何使用 ASP.NET MVC 和 Visual Studio 为 web 开发教程应用程序. MVC 音乐商店是一个轻量级的示例存储实现它卖音乐专辑在线,并实现 ...

随机推荐

  1. SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块

    \(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...

  2. 解决部分在Debug模式下程序没问题但是Release模式下出现问题的方法

    编译策略介绍 关于优化级别:GCC_OPTIMIZATION_LEVEL 描述如下 None: Do not optimize.  [-O0]With this setting, the compil ...

  3. 6.动态sql - if

    满足条件的数据 mapper.xml 满足if条件就执行,不满足就不加 <select id="selectStateByTitle" parameterType=" ...

  4. mybatis插入是返回主键id

    <!-- 插入数据:返回记录的id值 --> <insert id="insertOneTest" parameterType="org.chench. ...

  5. JDBC常用套路

    1.连接数据库.使用查询功能 //1.获取数据库连接 Connection con=JDBCTools.getConnection(); String sql="select * from ...

  6. tfs强行签入和删除工作区

    作者:为爱痴狂 原文:http://www.cnblogs.com/splyn/archive/2011/10/31/2230213.html 域用户被网络管理员重建,或者其他用户牵出文档,导致的TF ...

  7. AnnotationConfigApplicationContext

    package com.test; import java.io.IOException; import java.io.InputStream; import java.net.URL; impor ...

  8. 在Pycharm上编写WordCount程序

    本篇博客将给大家介绍怎么在PyCharm上编写运行WordCount程序. 第一步 下载安装PyCharm 下载Pycharm PyCharm的下载地址(Linux版本).下载完成后你将得到一个名叫: ...

  9. SQL 行转列的两种做法

    if object_id('tb')is not null drop table tbGocreate table tb(姓名 varchar(10),课程 varchar(10),分数 int)in ...

  10. Web开发中FormData对象的使用

    参考: FormData 对象的使用 - Web API 接口 | MDN