天天看点

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

本节书摘来自异步社区《精通 asp.net mvc 5》一书中的第2章,第2.3节,作者: 【美】adam freeman(弗瑞曼 a.),译者: 张成彬 , 徐燕萍 , 李萍 , 林逸 责编: 张涛, 更多章节内容可以访问云栖社区“异步社区”公众号查看。

前述示例的输出并不是html——只是一个字符串<code>“hello world”</code>。为了产生一个对浏览器请求进行响应的html,则需要一个视图(view)。

要做的第一件事是修改<code>index</code>动作方法,如清单2-3所示。

清单2-3 在<code>homecontroller.cs</code>文件中修改控制器,以渲染一个视图

清单2-3中的修改以黑体显示。当从一个动作方法返回一个<code>viewresult</code>对象时,便是在指示mvc去渲染一个视图。调用不带参数的view方法,便可以创建这个<code>viewresult</code>对象。这是在告诉<code>mvc</code>,去渲染该动作的默认视图。

如果此时运行该应用程序便可以看到,<code>mvc</code>框架正试图查找要使用的默认视图,并显示如图2-9所示的错误消息。

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

该错误消息是很有帮助的。它不仅解释了mvc未找到该动作方法的视图,还显示出查找了哪些地方。这是mvc约定的另一个很好的例子:视图是通过命名约定与动作方法相关联的。这个动作方法称为<code>“index”</code>,控制器称为<code>“home”</code>,从图2-9可以看出,mvc试图在<code>“views”</code>文件夹中查找具有这一名称的不同文件。

创建视图最简单的方法是要求visual studio来做这件事。在<code>homecontroller.cs</code>文件的代码编辑窗口中定义<code>index</code>动作方法的任意地方右击,然后从弹出的菜单中选择<code>“add view</code>(添加视图)”,如图2-10所示。

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

visual studio将显示<code>“add view(添加视图)”</code>对话框,让你配置待创建视图文件的初始内容。将<code>“view name(视图名)”</code>设置为<code>“index”(与该视图相关联的动作方法的名称,这是另一个约定)</code>,将<code>“template(模板)”</code>设置为<code>“empty (without model)”(空模板无模型)</code>,让<code>“create as a partial view(创建为分部视图)”</code>和<code>“use a layout page(使用布局页)”</code>复选框处于未选状态,如图2-11所示。此时不必急着了解这些选项的含义,在后面的章节中将有详细解释。单击<code>“add(添加)”</code>按钮,创建这一新的视图文件。

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

visual studio将在<code>views\home</code>文件夹中创建一个名称为<code>“index.cshtml”</code>的视图文件。如果未得到这一结果,请删除已创建的文件,再重试一次。这是mvc框架的另一个约定:视图被放置在views文件夹中,文件夹的结构是与其关联的控制器名称相对应的。

提示:

<code>.cshtml</code>文件扩展名表明这是一个由razor进行处理的c#视图。mvc的早期版本依托于aspx视图引擎之上,其视图文件的扩展名为.aspx。

上述“add view(添加视图)”对话框中所选择的值的结果是让visual studio创建最基本的视图,其内容如清单2-4所示。

清单2-4 index.cshtml文件的初始内容

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

visual studio会打开这一个<code>index.cshtml</code>文件,以便编辑。可以看出,该文件主要含有html语句。不同的是,会看到如下所示的部分。

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

这是一个将由razor视图引擎进行解释的表达式,razor引擎处理视图内容并生成发送给浏览器的html。这是一个简单的razor表达式,它告诉razor未选用布局,布局类似于发送给浏览器的html模板(将在第5章中描述)。此刻打算先忽略razor,稍后再回过头来讨论。现在对<code>index.cshtml</code>文件添加一些内容,如清单2-5中的黑体所示。

清单2-5 在index.cshtml中添加到视图的html

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

这一添加显示了另一条简单消息(用html标记显示出来的消息,而不是前面那种由动作方法显示的字符串)。从<code>“debug(调试)”</code>菜单中选择<code>“start debugging(开始调试)”</code>,以运行该应用程序并测试该视图,看到的情况应该类似于图2-12。

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

在最初编辑index动作方法时,它返回的是一个字符串值。这意味着mvc除了把这个字符串值传递给浏览器之外,未做其他事情。现在,index方法返回了一个<code>viewresult</code>,mvc框架渲染了一个视图并返回了它所产生的html。清单2-4并未告诉mvc应该使用哪一个视图,因此它会运用命名约定自动寻找一个视图。该约定是,视图具有动作方法的名称,并包含在以控制器命名的文件夹之中:<code>views/home/index.cshtml。</code>

除了字符串和<code>viewresult</code>对象之外,也可以从动作方法返回其他结果。例如,如果返回一个<code>redirectresult</code>,浏览器将被重定向到另一个url。如果返回一个<code>httpunauthorizedresult</code>,会强迫用户进行登录。这些对象统称为动作结果(action result),它们都派生于<code>actionresult</code>类。动作结果系统使开发者能够在动作中封装并重用常用的响应,第17章将对其做更多介绍并演示一些更复杂的运用。

web应用程序平台的关键是构造并显示动态输出。在mvc中,控制器的工作是构造一些数据,并将其传递给视图,而视图则负责把它渲染成html。

注:

现在有很多人都把“渲染”说成“呈现”,其实这种说法是不正确的。web页面从服务器到浏览器的整个呈现过程实际上分为三步:第一步是通过视图引擎对视图文件进行解释,将视图文件中的代码转换成html标记,这一步叫做渲染;第二步是将渲染后的html标记传递给客户端浏览器,这一步是页面的传递;第三步是浏览器接收到html后对其进行处理并呈现为web页面,这一步才叫做呈现。由此可见,渲染是把页面的非html代码(控件、页面代码等)转换成html标记,这一步工作是由服务器完成的。而呈现是将html显示成web页面,这一步工作是由浏览器完成的。渲染和呈现是整个页面处理过程的两个不同阶段,更不能把这两步工作混谈为只有“呈现”这一步。

将数据从控制器传递给视图的一种方式是使用<code>viewbag</code>(视图包)对象,它是controller基类的一个成员。<code>viewbag</code>是一种动态对象,可以给它赋任意属性,使这些属性的值在随后渲染的视图中是可用的。清单2-6演示了在<code>homecontroller.cs</code>文件中以这种方式传递一些简单的动态数据。

清单2-6 在<code>homecontroller.cs</code>文件中设置一些视图数据

当对<code>viewbag.greeting</code>属性进行赋值时,便是为视图提供数据。<code>greeting</code>属性直到对其赋值的那一刻才会形成——这让作者能够以自如而流畅的方式将数据从控制器传递给视图,而不必提前定义类。在视图中再次查阅<code>viewbag.greeting</code>属性,便可获得其数据值。正如清单2-7所演示的那样,它显示了对<code>index.cshtml</code>文件所做的相应更改。

清单2-7 在<code>homecontroller.cs</code>文件中接收<code>viewbag</code>的数据值

《精通 ASP.NET MVC 5》----2.3 渲染Web页面

添加到清单2-7的是一个razor表达式。当在控制器的index方法中调用view方法时,mvc框架会定位<code>index.cshtml</code>视图文件,并要求razor视图引擎解析该文件的内容。razor会寻找类似于在该清单中所添加的这种表达式,并处理它们。在这个例子中,处理该表达式意味着,在视图中插入作者在动作方法中赋给<code>viewbag.greeting</code>属性的值(这就是译者前面所提到的视图渲染过程)。

对属性名称<code>greeting</code>没有特别的要求,用任意属性名来代替,照样会正常工作,只要在控制器中使用的名称与视图中使用的名称相匹配即可。当然,通过对多个属性赋值,可以将多个数据值从控制器传递到视图。启动该项目,可以看到这些修改的效果,如图2-13所示。

《精通 ASP.NET MVC 5》----2.3 渲染Web页面