添加视图

概述

在这一部分我们添加一个新的控制器HelloWorldController类,以便使用视图来向客户端展示HTML格式的响应结果。

我们将使用Razor视图引擎创建一个视图。Razor视图模板以.cshtml扩展名结尾,它提供了一种简洁的方式来创建HTML输出流。Razor视图大大减少了在书写视图模板文件时所需要输入的字符,提供了一个最快捷,最简便的编码方式。

(注意:之前版本的asp.net mvc,可以选择视图引擎,在Asp.net MVC5中,默认的只有一种方式,也就是会生成.cshtml的文件,这里也就称为Razor视图引擎了。)

添加视图

这里,我们在HelloWorldController类的Index方法中添加使用一个视图。在修改前的Index方法中返回一个字符串,我们修改这个方法来使它返回一个视图,代码如下所示。

public class HelloWorldController : Controller
{
    //
    // GET: /HelloWorld/
    public ActionResult Index()
    {
        return View();
    }
}

这段代码表示Index方法使用一个视图模板来在浏览器中生成HTML格式的页面文件。接着,让我们来添加一个Index方法所使用的视图模板。在Index方法中点击鼠标右键,然后点击“添加视图”,将会弹出一个“添加视图”对话框。

版本 ASP.NET mvc3添加视图的方式(该图来源于网络)

ASP.NET MVC5添加视图的方式

在该对话框中,不做任何修改,直接点击添加按钮,观察解决方案资源管理器中,在项目下的Views文件夹下创建了一个HelloWorld文件夹,并且在该文件夹中创建了一个Index.cshtml文件,同时该文件呈打开状态,如图所示。

视图模板文件被创建并呈打开状态

让我们在 Index.cshtml视图模板文件中追加一些文字,代码如下:

 @{
     ViewBag.Title = "Index";
 }
 
 <h2>首页</h2>
 <p>这是我的第一个视图模版</p>

右键Index.cshtml文件,在浏览器中浏览。如图

(注意:这地方跟之前版本也有区别,之前版本好像是不能直接右键在浏览器中查看的。印象中是,机子上只有一个版本,无法求证了。)

由于在Index方法中并没有做任何事情,只是简单地一行代码—“return View()”,该行代码表示我们使用一个视图模板文件来在浏览器中展示响应结果。因为我们并没有显式指定使用哪个视图模板文件,所以使用了默认的Views文件夹下的HelloWorld文件夹下的Index.cshtml视图模板文件。该视图模板文件中只有简单的两行文字,在浏览器中的显示结果如图所示。

看一下url,发现url直接把完整的路由给拼上去了。右键在浏览器中浏览还是非常方便的,毕竟之前一直在做webform项目,习惯了。

至于为什么显示一个空按钮和Application name,是因为创建视图的时候,默认选择了空的布局页。

布局页代码:


 <!DOCTYPE html>
 <html>
 <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>@ViewBag.Title - My ASP.NET Application</title>
     <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
     <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
     <script src="~/Scripts/modernizr-2.6.2.js"></script>
 </head>
 <body>
     <div class="navbar navbar-inverse navbar-fixed-top">
         <div class="container">
             <div class="navbar-header">
                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                     <span class="icon-bar"></span>
                     <span class="icon-bar"></span>
                     <span class="icon-bar"></span>
                 </button>
                 @Html.ActionLink("Application name", "Index", "Home", null, new { @class = "navbar-brand" })
             </div>
             <div class="navbar-collapse collapse">
                 <ul class="nav navbar-nav">
                 </ul>
             </div>
         </div>
     </div>
 
     <div class="container body-content">
         @RenderBody()
         <hr />
         <footer>
             <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
         </footer>
     </div>
 
     <script src="~/Scripts/jquery-1.10.2.min.js"></script>
     <script src="~/Scripts/bootstrap.min.js"></script>
 </body>
 </html>

修改视图,修改应用程序的页面布局

首先,让我们修改页面中的按钮和Appliication name。这段文字是所有页面中的公共大标题,在这个应用程序中,虽然所有页面中都显示了这个共同的大标题,但只有一处地方对其进行了设置。打开解决方案资源管理器中Views文件夹下的Shared文件夹下的_Layout.cshtml文件。该文件被称为布局页面,位于公有文件夹Shared下,被所有其他网页所共用。

浏览结果

布局页代码


 <!DOCTYPE html>
 <html>
 <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>@ViewBag.Title - My ASP.NET Application</title>
     <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
     <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
     <script src="~/Scripts/modernizr-2.6.2.js"></script>
 </head>
 <body>
     <div class="navbar navbar-inverse navbar-fixed-top">
         <div class="container">
             <div class="navbar-header">
                 <button type="button"  class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    这是布局页的按钮
                 </button>
                 @Html.ActionLink("我的应用程序", "Index", "Home", null, new { @class = "navbar-brand" })
             </div>
             <div class="navbar-collapse collapse">
                 <ul class="nav navbar-nav">
                 </ul>
             </div>
         </div>
     </div>
 
     <div class="container body-content">
         @RenderBody()
         <hr />
         <footer>
             <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
         </footer>
     </div>
 
     <script src="~/Scripts/jquery-1.10.2.min.js"></script>
     <script src="~/Scripts/bootstrap.min.js"></script>
 </body>
 </html>

布局模板页允许你统一在一个地方指定整个Web应用程序或Web网站的所有HTML页面的布局方法。请注意文件底部的“@RenderBody()”代码行。@RenderBody()是一个占位符,代表了所有你创建出来的实际应用的视图页面,在这里统一指定。

现在,让我们修改Index视图页面的标题。

 @{
     ViewBag.Title = "这是我的第一个视图";
 }
 
 <h2>首页</h2>
 <p>这是我的第一个视图模版</p>

ViewBag对象的Title属性代表了显示该页面时的浏览器中的标题文字。让我们回头看一下布局模板文件,在该文件的<head>区段中的<title>标签中使用了这个值来作为浏览器中的网页标题。同时,通过这种方法,你可以很容易地在你的视图模板文件与布局模板文件之间进行参数的传递。

修改后浏览

为什么在上面标红框的地方会出现两个呢?

在_layout.cshtml中的title标签中的代码为

  <title>@ViewBag.Title - My ASP.NET Application</title>

可见可以通过@ViewBag这种方法,你可以很容易地在你的视图模板文件与布局模板文件之间进行参数的传递。

在页面右键查看源代码,你会发现在原来 @RenderBody()所在的地方被Index.cshtml的代码所替代。

将控制器中的数据传递给视图

在我们使用数据库并介绍模型之前,首先我们介绍一下如何将控制器中的信息传递给视图。调用控制器类来进行响应,接收到的URL请求。你可以在控制器类中进行对接收到的页面参数进行处理的代码,你可以在控制器类中书写从数据库中获取数据的代码,你也可以在控制器类中书写代码来决定返回给客户端什么格式的响应文件。控制器可以利用视图模板文件来生成HTML格式的响应文件并显示在浏览器中。

控制器类负责提供视图模板文件在生成HTML格式的响应文件时所需要的任何数据或对象。一个视图模板文件不应该执行任何业务逻辑,也不应该直接和数据库进行交互。它只能和控制器类进行交互,获取控制器类所提供给它的数据,这样可以使你的代码更加清晰,容易维护。

现在在我们在HelloWorldController控制器类中添加一个带有两个参数的Welcome方法,Welcome方法直接向浏览器输出这两个参数的参数值。这里,我们修改该方法使其不再直接输出数据,而是使用一个视图模板。该视图模板将生成一个动态的响应流,这意味着我们需要将数据从控制器类传递给视图以便利用该数据来生成该响应流。我们在该控制器类中将视图模板所需要的数据送入一个ViewBag对象中,该对象可以被视图模板直接接收。

在Welcome方法中为ViewBag对象添加一个Message属性与NumTimes属性,并且将属性值分别设定为经过处理后的name参数值与numTimes参数值。ViewBag对象是一个动态对象,你可以为它添加任何属性并赋上属性值。在未赋值之前该属性是不生效的,直到你赋值为止。

         public ActionResult Welcome(string name, int numTimes = )
         {
             ViewBag.Message = "Hello " + name;
             ViewBag.NumTimes = numTimes;
             return View();
         }

编译,然后按照上面为index添加视图的方式添加视图。

找到Welcome.cshtml文件,打开,修改里面的代码,让浏览器显示URL地址中传入的name参数中设定的文字,显示次数等于URL地址中传入的numTimes参数中设定的次数。

修改后的代码如下:

 @{
     Layout = null;
 }
 
 <!DOCTYPE html>
 
 <html>
 <head>
     <meta name="viewport" content="width=device-width" />
     <title>Welcome</title>
 </head>
 <body>
     <div> 
         <ul>
             @for (int i = 0; i < ViewBag.NumTimes; i++)
             {
                 <li>
                     @ViewBag.Message
                 </li>
             }
         </ul>
     </div>
 </body>
 </html>

右键在浏览器中浏览,修改url地址为:http://localhost:4585/HelloWorld/Welcome?name=wolfy&numtimes=4

该地址栏中的页面参数将会自动传递给控制器。控制器将会把这些参数值放入ViewBag对象中并且传递给视图。视图再在浏览器中显示这些数据。

这里,我们使用了模型“M”的一种方式,但是不是数据库的方式。在下一节中,我们将创建一个数据库,并且介绍如何对该数据库中的数据进行处理。

总结

在上面的示例中,我们使用ViewBag对象将控制器的数据传递给视图。

ViewBag也可以在视图模版和布局模版之间传递数据。

@RenderBody()占位符,相当于webform中contentplaceholder。

参考文章:

http://www.asp.net/mvc/tutorials/mvc-5/introduction/adding-a-view