码迷,mamicode.com
首页 > Web开发 > 详细

ASP.NET MVC

时间:2016-06-21 07:50:07      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:

  ASP.NET MVC

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

第17章  ASP.NET MVC基础

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

第17章  ASP.NET MVC基础

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

第17章  ASP.NET MVC基础

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

第17章  ASP.NET MVC基础

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

第17章  ASP.NET MVC基础

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

第17章  ASP.NET MVC基础

在ASP.NET应用程序开发中,开发人员很难将ASP.NET应用程序进行良好分层并使相应的页面进行相应的输出,例如页面代码只进行页面布局和样式的输出而代码页面只负责进行逻辑的处理。为了解决这个问题,微软开发了MVC开发模式方便开发人员进行分层开发。

17.1  了解MVC

MVC是一个设计模式,MVC能够将ASP.NET应用程序的视图、模型和控制器进行分开,开发人员能够在不同的层次中进行应用程序层次的开发,例如开发人员能够在视图中进行页面视图的开发,而在控制器中进行代码的实现。

17.1.1  MVC和Web Form

在ASP.NET WebForm的开发当中,用户能够方便的使用微软提供的服务器控件进行应用程序的开发,从而提高开发效率。虽然ASP.NET Web Form提高了开发速度、维护效率和代码的复用性,但是ASP.NET现有的编程模型抛弃了传统的网页编程模型,在很多应用问题的解决上反而需要通过复杂的实现完成。

在ASP.NET MVC模型中,ASP.NET MVC模型给开发人员的感觉仿佛又回到了传统的网页编程模型中(如ASP编程模型),但是ASP.NET MVC模型与传统的ASP同样是不同的编程模型,因为ASP.NET MVC模型同样是基于面向对象的思想进行应用程序的开发。

相比之下,ASP.NETMVC模型是一种思想,而不是一个框架,所以ASP.NET MVC模型与ASP.NET Web Form并不具有可比性。同样ASP.NET MVC模型也不是ASP.NET Web Form 4.0,这两个开发模型就好比一个是汽车一个是飞机,而两者都能够达到同样的目的。

ASP.NET MVC模型是另一种Web开发的实现思路,其实现的过程并不像传统的ASP.NET应用程序一样。当用户通过浏览器请求服务器中的某个页面时,其实是实现了ASP.NET MVC模型中的一个方法,而不是具体的页面,这在另一种程度上实现了URL伪静态。当用户通过浏览器请求服务器中的某一个路径时,ASP.NET MVC应用程序会拦截相应的地址并进行路由解析,通过应用程序中编程实现展现一个页面给用户,这种页面展现手法同传统的ASP.NET Web From应用程序与其他的如ASP,PHP等应用程序都不相同。

同时,随着互联网的发展,搜索引擎在Web开发中起着重要的作用,这就对页面请求的地址有了更加严格的要求。例如百度、谷歌等搜索引擎会对目录形式的页面路径和静态形式的页面路径收录的更好,而对于动态的如abc.aspx?id=1&action=add&t=3这种样式的页面路径不甚友好。

另外,所有引擎又在一定程度上决定了Web应用的热度,例如当在百度中搜索“鞋”这个关键字时,如果搜索的结果中客户的网站在搜索结果的后几页,用户通常不会进行翻页查询,相比之下用户更喜欢在搜索结果中查看前几页的内容。

ASP.NET MVC开发模型在用户进行页面请求时会进行URL拦截并通过相应的编程实现访问路径和页面的呈现,这样就能够更加方便的实现目录形式的页面路径和静态形式,对于Web应用动态的地址如abc.aspx?id=1&action=add&t=3可以以abc/action/id/add的形式呈现,这样就更加容易的被搜索引擎所搜录。

注意:ASP.NET MVC模型和ASP.NET Web Form并不具备可比性,因为ASP.NET MVC模型和ASP.NET Web Form是不同的开发模型,而ASP.NET MVC模型和ASP.NET Web Form在各自的应用上都有有点和缺点,并没有哪个开发模型比另一个模型好之说。

17.1.2  ASP.NETMVC的运行结构

在ASP.NET MVC开发模型中,页面的请求并不是像传统的Web应用开发中的请求一样是对某个文件进行访问,初学者可能会在一开始觉得非常的不适应。例如当用户访问/home/abc.aspx时,在服务器的系统目录中一定会存在abc.aspx这个页面,而对于传统的页面请求的过程也非常容易理解,因为在服务器上只有存在了home文件夹,在home文件夹下一定存在abc.aspx页面才能够进行相应的页面访问。

对于ASP.NET MVC开发模型而言,当请求URL路径为“/home/abc.aspx”时,也许在服务器中并不存在相应的abc.aspx页面,而可能是服务器中某个方法。在ASP.NET MVC应用程序中,页面请求的地址不能够按照传统的概念进行分析,要了解ASP.NETMVC应用程序的页面请求地址就需要了解ASP.NET MVC开发模型的运行结构。ASP.NET MVC开发模型的运行结构如图17-1所示。

图17-1  ASP.NET MVC开发模型

正如图17-1所示,ASP.NET MVC开发模型包括三个模块,这三个模块分别为MVC的M、V、C,其中M为Models(模型)、V为Views(视图)、C为Controllers(控制器),在ASP.NET MVC开发模型中,这三个模块的作用分别如下所示。

q  Models:Models负责与数据库进行交互,在ASP.NET MVC框架中,使用LINQ进行数据库连接和操作。

q  Views:Views负责页面的页面呈现,包括样式控制,数据的格式化输出等。

q  Controllers:Controllers负责处理页面的请求,用户呈现相应的页面。

与传统的页面请求和页面运行方式不同的是,ASP.NET MVC开发模型中的页面请求首先会发送到Controllers中,Controllers再通过Models进行变量声明和数据读取。Controller通过页面请求和路由设置呈现相应的View给浏览器,用户就能够在浏览器中看到相应的页面。这里讲解ASP.NETMVC开发模型的工作流程可能会让读者感到困惑,具体ASP.NET MVC开发模型的工作流程会在后面详细讲解。

17.2  ASP.NET MVC基础

ASP.NET MVC开发模型和ASP.NET Web From开发模型并不相同,ASP.NET MVC为ASP.NET Web开发进行了良好的分层,ASP.NET MVC开发模型和ASP.NET Web From开发模型在请求处理和应用上都不尽相同,只有了解ASP.NET Web From开发模型的基础才能够高效的开发MVC应用程序。

17.2.1  安装ASP.NET MVC

ASP.NET MVC是微软推出的最新的ASP.NET Web开发模型,开发人员可以在微软的官方网站上下载ASP.NET MVC安装程序,也能够使用光盘中附属的ASP.NET MVC安装程序进行安装,光盘中附带的是ASP.NET MVC beta版本,正式版同beta版本基本上没有任何区别,开发人员可以在官方网站下载最新的安装程序。单击下载或附录中的AspNetMVCBeta-setup.msi进行ASP.NET MVC开发模型的安装和相应示例的安装,如图17-2所示。

用户单击ASP.NETMVC安装界面中的【Next】按钮进入ASP.NET MVC安装的用户条款界面,单击【I accept the terms intthe License Agreement】复选框同意ASP.NET MVC用户条款,如图17-3所示。同意后单击【Next】按钮进入ASP.NET MVC安装准备界面,进入安装界面后单击【Install】按钮进行安装。

  

图17-2  ASP.NET MVC安装界面                 图17-3  ASP.NET MVC用户条款

注意:在安装ASP.NET MVC前必须安装Visual Studio 2008进行ASP.NET MVC应用程序的开发,安装完成ASP.NET MVC应用程序后就能够在Visual Studio 2008进行创建ASP.NETMVC应用程序。

单击【Install】按钮应用程序,系统就会在计算机中安装ASP.NET MVC开发模型和Visual Studio 2008中进行ASP.NET MVC程序开发所需要的必备组件以便在Visual Studio 2008为开发人员提供原生的ASP.NET MVC开发环境。安装完毕后,安装程序会提示ASP.NET MVC安装程序已经安装完毕,安装完毕后开发人员就能够使用VisualStudio 2008开发ASP.NET MVC应用程序。安装过程如图17-4和17-5所示。

 

图17-4  ASP.NET MVC安装                  图17-5  ASP.NET MVC安装完毕

17.2.2  新建一个MVC应用程序

安装完成ASP.NETMVC开发模型后就能够在VisualStudio 2008中创建ASP.NET MVC应用程序进行ASP.NET MVC应用程序的开发,安装ASP.NET MVC开发模型后,Visual Studio 2008就能够为ASP.NET MVC提供原生的开发环境。在菜单栏中选择【文件】选项,单击【文件】选项在下拉菜单中选择【新建项目】就能够创建ASP.NET MVC应用程序,如图17-6所示。

单击【确定】按钮后就能够创建ASP.NETMVC应用程序。VisualStudio 2008为ASP.NET MVC提供了原生的开发环境,以及智能提示,开发人员在进行ASP.NET MVC应用程序开发中,Visual Studio 2008同样能够为ASP.NET MVC应用程序提供关键字自动补完、智能解析等功能以便开发人员高效的进行ASP.NETMVC应用程序的开发。创建ASP.NETMVC应用程序后,系统会自动创建若干文件夹和文件,如图17-7所示。

 

图17-6  创建ASP.NET MVC应用程序                 图17-7  自动创建的文件

在自动创建的文件中,这些文件包括ASP.NET MVC应用程序中最重要的文件夹用于分层开发,这些文件夹分别为Models、Views和Controllers,分别对应ASP.NET MVC开发模型的Models(模型)、Views(视图)、Controller(控制器),开发人员能够在相应的文件夹中创建文件进行ASP.NETMVC应用程序的开发。

17.2.3  ASP.NETMVC应用程序的结构

在创建完成ASP.NETMVC应用程序,系统会默认创建一些文件夹,这些文件夹不仅包括对应ASP.NET MVC开发模型的Models、Views和Controllers文件夹,还包括配置文件Web.config、Global.aspx和Default.aspx。

1.Default.aspx:页面驱动

Default.aspx用于ASP.NET MVC应用程序程序的驱动,当用户执行相应的请求时,Default.aspx能够驱动ASP.NET MVC应用程序页面的处理和生成,Default.aspx页面代码如下所示。

<%@ Page

Language="C#"AutoEventWireup="true" CodeBehind="Default.aspx.cs"Inherits="_17_1._Default" %>

Default.aspx页面代码同传统的ASP.NET Web Form基本相同,但Default.aspx只是用于MVC应用程序的驱动。Default.aspx使用IHttpHandler类获取和发送HTTP请求,Default.aspx.cs页面代码如下所示。

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.UI;

namespace _17_1

{

    publicpartial class _Default : Page

    {

       public void Page_Load(object sender, System.EventArgs e)

        {

           HttpContext.Current.RewritePath(Request.ApplicationPath);                           //拦截虚拟目录根路径

           IHttpHandler httpHandler = new MvcHttpHandler();

           httpHandler.ProcessRequest(HttpContext.Current);

        }

    }

}

上述代码用于ASP.NETMVC应用程序的驱动。在ASP.NETMVC应用程序被运行时,会拦截虚拟目录的根路径将请求发送到Controllers实现。

2.Global.asax:全局配置文件

Global.asax是全局配置文件,在ASP.NET MVC应用程序中的应用程序路径是通过Global.asax文件进行配置和实现的,Global.asax页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                          //使用Mvc命名空间

using System.Web.Routing;                                                                                                   //使用Mvc命名空间

namespace _17_1

{

    // Note:For instructions on enabling IIS6 or IIS7 classic mode,

    // visithttp://go.microsoft.com/?LinkId=9394801

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                    //配置路由名称

               "{controller}/{action}/{id}",                                                                        //配置访问规则

                new { controller = "Home",action = "Index", id = "" }                          //为访问规则配置默认值

           );                                                                                                                           //配置URL路由

        }

       protected void Application_Start()

        {

           RegisterRoutes(RouteTable.Routes);

        }

    }

}

上述代码在应用程序运行后能够实现相应的URL映射,当用户请求一个页面时,该页面会在运行时启动并指定ASP.NET MVC应用程序中URL的映射以便将请求提交到Controllers进行相应的编程处理和页面呈现。

Global.asax实现了伪静态的URL配置,例如当用户访问/home/guestbook/number服务器路径时,Global.asax通过URLRouting够实现服务器路径/home/guestbook/number到number.aspx的映射。有关URLRouting的知识会在后面的小结中讲解。

注意:在ASP.NET MVC开发模型中,浏览器地址栏的URL并不能够被称为是伪静态,为了方便读者的理解可以暂时称为伪静态,但是最主要的是要理解访问的路径并不像传统的Web开发中那样是访问真实的某个文件。

3.Models、Views和Controllers三层结构

Models、Views和Controllers文件夹是ASP.NET MVC开发模型中最为重要的文件夹,虽然这里以文件夹的形式呈现在解决方案管理器中,其实并不能看作传统的文件夹。Models、Views和Controllers分别用于存放ASP.NET MVC应用程序中Models、Views和Controllers的开发文件。在创建ASP.NET MVC应用程序后,系统会自行创建相应的文件,这里也包括ASP.NET MVC应用程序样例,如图17-8和图17-9所示。

 

图17-8  Views视图文件夹           图17-9  Controllers控制器文件夹

正如图17-8、17-9所示,在样例中分别创建了若干Controllers控制器文件,以及Views页面文件。运行ASP.NETMVC应用程序后,用户的请求会发送到Controllers控制器中,Controllers控制器接受用户的请求并通过编程实现Views页面文件的映射。

17.2.4  运行ASP.NET MVC应用程序

创建ASP.NET MVC应用程序后就能够直接运行ASP.NET MVC应用程序,默认的ASP.NET MVC应用程序已经提供了样例方便开发人员进行编程学习,单击【F5】运行ASP.NET MVC应用程序,运行后如图17-10所示。

在创建ASP.NET MVC应用程序后系统会创建样例,图17-10显式的就是ASP.NET MVC默认运行界面,单击旁边的【About Us】连接页面跳转到相应的页面,如图17-11所示。

  

图17-10  ASP.NET MVC应用程序初始界面                     图17-11  About页面

当单击【About Us】链接后,页面会跳转到关于页面,页面URL为http://localhost:2448/Home/About。在ASP.NET MVC应用程序中,URL路径的请求方式与传统的ASP.NET Web Form应用程序不同,开发人员可以发现,在服务器文件中并没有/Home/About/index.aspx文件也没有/Home/About/这个目录。

注意:在ASP.NET MVC应用程序中,这里再三强调,其URL并不是服务器中的某个文件而是一种地址映射。

在服务器中没有/Home/About/index.aspx文件也没有/Home/About/这个目录,因为/Home/About中所呈现的页面是通过Controller控制器和Global.ascx进行相应的文件的路径的映射的,关于地址映射的内容会在后面的小结中详细讲解。

17.3  ASP.NET MVC原理

运行了ASP.NET MVC应用程序后,就能够通过相应的地址访问不同的页面。在ASP.NET MVC应用程序中,应用程序中页面的URL并不是在服务器中实际存在的页面或目录而是访问了相应的方法,ASP.NETMVC应用程序通过Global.ascx和Controllers实现了URL映射。

17.3.1  ASP.NETMVC运行流程

在运行ASP.NET MVC应用程序后,会发现访问不同的ASP.NET MVC应用程序页面时,其URL路径并不会呈现相应的.aspx后缀。同样当访问相应的ASP.NET MVC应用程序页面,在服务器中并不存在对应的页面。为了了解如何实现页面映射,就需要了解ASP.NET MVC应用程序的运行流程。

在ASP.NET MVC程序中,应用程序通过Global.ascx和Controllers实现了URL映射。当用户进行ASP.NET MVC程序的页面请求时,该请求首先会会被发送到Controllers控制器中,开发人员能够在控制器Controllers中创建相应的变量并将请求发送到Views视图中,Views视图会使用在Controllers控制器中通过编程方式创建相应的变量并呈现页面在浏览器中。当用户在浏览器中对Web应用进行不同的页面请求时,该运行过程将会循环反复。

对于Models而言,Controller通常情况下使用Models读取数据库。在Models中,Models能够将传统的关系型数据库映射成面向对象的开发模型,开发人员能够使用面向对象的思想进行数据库的数据存取。Controllers从Model中读取数据并存储在相应的变量中,如图17-12所示。

图17-12  ASP.NET MVC运行流程

正如图17-12所示,在用户进行页面请求时,首先这个请求会发送到Controllers中,Controllers从Models中读取相应的数据并填充Controllers中的变量,Controllers接受相应请求再将请求发送到Views中,Views通过获取Controllers中的变量的值进行整合并生成相应的页面到用户浏览器中。

在Models中需要将数据库抽象成面向对象中的一个对象,开发人员能够使用LINQ进行数据库的抽象,这样就能够方便的将数据库中的数据抽象成相应的对象并通过对象的方法进行数据的存取和更新。

17.3.2  ASP.NETMVC工作原理

正如上一节中讲解的ASP.NETMVC工作流程,在ASP.NETMVC应用程序中,系统默认创建了相应的文件夹进行不同层次的开发,在ASP.NET MVC应用程序的运行过程中,同样请求会发送到Controllers中,这样就对应了ASP.NET MVC应用程序中的Controllers文件夹,Controllers只负责数据的读取和页面逻辑的处理。在Controllers读取数据时,需要通过Models中的LINQ to SQL从数据中读取相应的信息,读取数据完毕后,Controllers再将数据和Controller整合并提交到Views视图中,整合后的页面将通过浏览器呈现在用户面前。

当用户访问http://localhost:2448/Home/About页面时,首先这个请求会发送到Controllers中,Controllers通过Global.ascx文件中的路由设置进行相应的URL映射,Global.ascx文件相应代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",

               "{controller}/{action}/{id}",

               new { controller = "Home", action = "Index", id ="" }                                             //配置路由

           );

        }

上述代码中实现了映射操作,具体是如何实现可以先无需关心,首先需要看看Controllers文件夹内的文件,以及Views文件夹的文件,如图17-13所示。

图17-13  Controller文件夹和Views文件夹

从图17-13中可以看出,在Views中包含Home文件夹,在Home文件夹中存在About.aspx和Index.aspx文件,而同样在Controllers文件夹中包含与Home文件夹同名的HomeController.cs文件。当用户访问http://localhost:2448/Home/About路径时,首先该路径请求会传送到Controller中。

注意:在Controllers文件夹中创建HomeController.cs文件同Home是同名文件,在Controllers中创建的文件,其文件名后的Controller.cs是不能更改的,所以HomeController.cs文件也可以看做是Home文件夹的同名文件。

在Controller中,Controller通过Global.ascx文件和相应的编程实现路径的映射,示例代码如下所示。

    [HandleError]

    publicclass HomeController : Controller

    {

       public ActionResult About()                                                                                                       //实现About页面

        {

           ViewData["Title"] = "About Page";

           return View();                                                                                                              //返回视图

        }

    }

上述代码实现了About页面的页面呈现,在运行相应的方法后会返回一个View,这里默认返回的是与Home的About方法同名的页面,这里是about.aspx,about.aspx页面代码如下所示。

<%@ Page

    Language="C#"

    MasterPageFile="~/Views/Shared/Site.Master"

    AutoEventWireup="true"CodeBehind="About.aspx.cs"Inherits="_17_1.Views.Home.About" %>

    <asp:ContentID="aboutContent" ContentPlaceHolderID="MainContent"runat="server">

        <h2>About Us</h2>

        <p>

            TODO: Put <em>about</em>content here.

        </p>

    </asp:Content>

将about.aspx页面中的文字进行相应的更改,示例代码如下所示。

<asp:Content ID="aboutContent"ContentPlaceHolderID="MainContent" runat="server">

   <h2>About Us</h2>

   <p>

        <spanstyle=”color:red”>这是一个关于页面</span>

   </p>

</asp:Content>

运行about.aspx页面,运行后如图17-14所示。

图17-14  修改后的About Us页面

从上述代码可以看出,Controllers与Global.ascx用于URL的映射,而Views用于页面的呈现。从这里可以看出,当用户访问http://localhost:2448/Home/About页面时,访问的并不是服务器中的/Home/About页面,而访问的是Controllers中的HomeControllers的About方法。

注意:ASP.NET MVC应用程序中的URL路径访问的并不是一个页面,而是一个方法,例如访问/Home/About页面就是访问的是HomeControllers中的About方法,而访问/Account/Login页面就是访问的是AccountControllers中的Login方法。

在ASP.NET MVC应用程序中,ASP.NET MVC应用程序的对应关系如图17-15所示。

图17-15  ASP.NET MVC应用程序关系图

在ASP.NET MVC应用程序中,HomeController.cs对应Views的Home文件夹,而其中的Index方法和About方法对应Index.aspx文件和About.aspx文件。

注意:在命名时,默认情况下XXXController.cs对应Views的XXX文件夹,而其中XXXController.cs中的YYY()方法对应XXX文件夹中的YYY.aspx,而访问路径为XXX/YYY是访问的是XXXController.cs中的YYY()方法。

实现相应的URL映射需要通过修改Global.ascx文件进行实现,如何通过修改Global.ascx文件进行不同的URL映射将在后面的小结中讲解。

17.4  ASP.NET MVC开发

在了解了ASP.NETMVC工作原理和工作流程,以及ASP.NETMVC中的URL映射基础原理,就能够进行ASP.NET MVC应用程序的开发,在进行ASP.NET MVC应用程序开发的过程中可以深入的了解ASP.NET MVC应用程序模型和URL映射原理。

17.4.1  创建ASP.NET MVC页面

ASP.NET MVC应用程序包括MVC三个部分,其中Models是用于进行数据库抽象,Views是用于进行视图的呈现而Controllers是用于控制器和逻辑处理,在创建ASP.NET MVC应用程序时,可以为ASP.NET MVC应用程序分别创建相应的文件。首先在Views文件夹中创建一个文件夹,这里创建一个Beta文件夹。创建文件夹后单击Beta文件夹,右击文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项,单击后系统会弹出对话框用于View文件的创建,如图17-16所示。

图17-16  创建View文件

在Views中可以创建MVC View Page用于Views文件的创建,从而用于在ASP.NET MVC应用程序中呈现相应页的视图,在Index.aspx中可以编写相应的代码用于视图的呈现,Index.aspx页面代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true" CodeBehind="Beta.aspx.cs"Inherits="_17_1.Views.Beta.Beta" %>

    <h2>AboutUs</h2>

        <p>

        <span style="color:red">这是一个测试页面</span>

        </p>

Index.aspx页面用于视图的呈现,在一个传统的ASP.NET应用程序窗体中,ASP.NET应用程序窗体是派生自System.Web.UI.Page的,而ASP.NET MVC应用程序页面代码需要派生自ViewPage,Index.aspx的cs文件代码在创建时与传统的ASP.NET应用程序窗体不同,示例页面代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

namespace _17_1.Views.Beta

{

    publicpartial class Index : ViewPage                                                                                              //派生自ViewPage

    {

    }

}

在完成Beta.aspx的创建后,在ASP.NET MVC应用程序开发模型中还需要创建Controllers用于接受用户请求和Beta.aspx页面同名的方法实现。单击Controllers文件夹,右击Controllers文件夹,在下拉菜单中选择【添加】选项,在【添加】选项中单击【新建项】选项。这里可以创建一个同名的类文件,如图17-17所示。

图17-17  创建Controllers文件

创建Controllers类文件时,创面的类文件的名称必须为Views文件夹中相应的视图文件夹的名称加上Controllers.cs,正如图17-17所示,如创建的是“Beta”文件夹,在创建Controllers时必须创建BetaControllers.cs,在创建相应的类文件后才能够拦截相应的URL并进行地址映射,创建后的Controllers类文件代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;                                                                                                                  //使用MVC命名空间

using System.Web.Mvc.Ajax;                                                                                                         //使用MVC命名空间

namespace _17_1.Controllers

{

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           return View();                                                                                                              //返回Index视图

        }

    }

}

这里值得注意的是,仅仅创建一个Index.aspx页面并不能够在浏览器中浏览Index.aspx页面,必须在相应的Controllers类文件中实现与Index.aspx页面文件同名的方法Index()才能够实现Index.aspx页面的访问。Views中的Index.aspx页面能够使用Controllers类文件中的Index方法中的变量进行数据呈现。单击【F5】运行页面,运行后如图17-18所示。

图17-18  MVC页面运行

这里讲解了如何手动创建ASP.NETMVC页面。在某些版本的VisualStudio中,安装了ASP.NETMVC开发包应用程序后,可能不会存在MVC文件的创建,这时只能通过创建ASP.NETWeb Form再通过编码实现。

如果希望能够创建ASP.NETMVC模板而不使用手动创建可以在C:\ProgramFiles\Microsoft ASP.NET\ASP.NET MVC Beta\Temp目录下将压缩包拷贝到相应的Visual Studio安装目录X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\中,拷贝后在开始菜单中选择“运行”,在窗口中输入cmd,就会弹出一个黑色的命令行窗口,在命令行输入cd X:\Microsoft Visual Studio9.0\Common7\IDE\ItemTemplates\CSharp\Web\2052\进入目录,输入devenv.exe /setup进行模板的安装,安装完成后就能够在添加新项中选择MVC应用程序模板。

17.4.2  ASP.NETMVC 数据呈现(ViewData)

在ASP.NET MVC应用程序中,Controllers负责数据的读取而Views负责界面的呈现,在界面的呈现中Views通常不进行数据的读取和逻辑运算,数据的读取和逻辑运算都交付给Controllers负责。为了能够方便的将Controllers与Views进行整合并在Views中呈现Controllers中的变量,可以使用ViewData整合Controllers与Views从而进行数据读取和显示。

在ASP.NET MVC应用程序的Views中,其值并不是固定的,而是通过Controllers传递过来的,在Controllers类文件中的页面实现代码中,可以需要使用ViewData进行值的传递,BetaControllers.cs中Index.aspx实现的Index()的方法示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()                                                                                              //实现Index方法

        {

           ViewData["beta"] = "这是一个ViewData字符串";                                                 //使用ViewData

           return View();                                                                                                              //返回视图

        }

    }

上述代码使用ViewData存储数据,ViewData的声明和赋值方式与Session对象相同,直接通过编写ViewData[键值的名称]=XXX进行相应的键值的赋值。如果需要在页面中进行相应的值的呈现,只需要输出ViewData[键值的名称]即可。

在ASP.NET MVC应用程序中,字符输出都需要呈现在Views视图中,在Controllers中进行ViewData变量的赋值,就需要在Views中输出相应的变量,BetaControllers.cs中的Index()方法实现的是Index.aspx页面,在Index.aspx可以使用ViewData["beta"]变量,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <spanstyle="color:Green"><%=ViewData["beta"]%></span>

    </p>

上述代码中在运行后会输出ViewData["beta"]变量中存储的值,运行后如图17-19所示。

图17-19  输出ViewData

ViewData不仅可以为某个具体的值,ViewData还可以是一个泛型变量,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           List<string> str = new List<string>();                                                                                //创建泛型变量

           str.Add("str字符串1<hr/>");                                                                                               //添加成员

           str.Add("str字符串2<hr/>");                                                                                               //添加成员

           str.Add("str字符串3<hr/>");                                                                                               //添加成员

           str.Add("str字符串4<hr/>");                                                                                               //添加成员

           ViewData["beta"] = str;                                                                                                        //赋值ViewData

           return View();                                                                                                                        //返回视图

        }

    }

在为ViewData赋值泛型变量后,在相应的View页面中也可以输出ViewData的值,示例代码如下所示。

    <h2>AboutUs</h2>

    <p>

        <span style="color:Red">这是一个测试页面</span><br/>

        <% foreach(string str inViewData["beta"] as List<string>) %>

        <% = str%>

    </p>

上述代码通过使用foreach进行ViewData变量中相应健值的值的遍历,运行后如图17-20所示。

图17-20  遍历ViewData变量的值

使用List类能够将数据库中的数据存放在泛型列表类中,开发人员能够将数据库中的数据遍历并存放在Controllers类文件中的页面实现的类的ViewData变量中,当需要遍历数据进行呈现时,例如新闻列表或者是论坛列表等,可以通过遍历ViewData变量的值遍历输出数据库中的数据。

17.4.3  ASP.NETMVC 跨页数据呈现(TempData)

ASP.NET MVC TempData同ASP.NET MVC ViewData一样,是在Controllers中声明的变量以便在Views中进行调用,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["beta"] = "TempData字符串";

           return View();

        }

    }

上述代码在Controllers中声明了TempData,在Views中的相应页面可以使用此TempData进行变量的输出,示例代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Beta.aspx.cs" Inherits="_17_1.Views.Beta.Index"%>

    <h2>AboutUs</h2>

    <p>

        <%=TempData["beta"] %>

    </p>

上述代码呈现了TempData变量的值,运行后如图17-21所示。

图17-21  显示TempData变量

在数据呈现上,TempData变量同ASP.NET MVC ViewData基本相同,但是TempData能够在跳转中保存值。当用户访问一个页面时,该页面的Controllers中包含TempData变量。当这个页面通过Redirect跳转到另一个页面时,另一个页面能够使用跳转页面的TempData变量。在跳转页面中,在跳转前可以编写TempData变量保存相应的值,示例代码如下所示。

   [HandleError]

    publicclass BetaController : Controller

    {

       public ActionResult Index()

        {

           TempData["Index"] = "这是跳转页面的字符串哦..";                                                        //编写TempData

           Response.Redirect("/Beta/Get");                                                                                       //页面跳转

           return View();                                                                                                                        //返回视图

        }

    }

上述忽代码编写了一个TempData变量并将页面跳转到Get.aspx,这里在Beta文件夹下创建一个Get.aspx页面读取相应的TempData变量的值。创建完成后,编写HTML代码如下所示。

<%@ Page

Language="C#"

AutoEventWireup="true"CodeBehind="Get.aspx.cs" Inherits="_17_1.Views.Beta.Get"%>

    <h2>接受传递的参数</h2>

        <p>

            <%=TempData["Index"] %>

        </p>

编写了页面代码后还不能对页面进行访问,由于MVC编程模型中路径是访问的Controller中的方法,所以还需要在Controller中实现Get页面的方法,示例代码如下所示。

       public ActionResult Get()

        {

           return View();                                                                                                                        //返回默认视图

        }

上述代码返回默认视图,当不给View方法进行参数传递,将会返回与方法同名的.aspx页面文件。这里没有对View方法传递参数,则返回的是Get.aspx页面视图,当用户访问/Beta/路径时,代码会创建一个TempData变量并跳转到/Beta/Get路径,在/Beta/Get路径相应的文件中可以获取跳转前的TempData变量的值,运行后如图17-22所示。

图17-22  接受TempData变量的值

在Get.aspx页面相应的实现代码中并没有声明任何的TempData变量,而是在跳转前的页面中声明的TempData变量,与ViewData相比跳转后的页面能够获取TempData变量的值而不能获取ViewData的值,这在某些应用场合如抛出异常等情况下非常适用。

注意:TempData变量在跳转中能够跨页面进行数据读取,但是跨页面跳转后TempData变量只能呈现一次。简单的说就是跳转的第一次能过获取跳转前页面的TempData变量的值,而再次操作时就无法使用跳转前页面的TempData变量值。

17.4.4  ASP.NET MVC页面重定向

在ASP.NET WebForm中,可以通过Response.Redirect(页面)的方法进行页面的重定向,在ASP.NET MVC编程模型中,也可以通过Response.Redirect(页面)的方法进行页面重定向。不仅如此,ASP.NET MVC编程模型还支持多种页面重定向方法,传统的页面重定向可以使用Response.Redirect(页面)方法,示例代码如下所示。

       public ActionResult Index()

        {

           Response.Redirect("/Beta/Get");                                                                    //Response.Redirect(页面)

           return View();                                                                                                     //返回视图

        }

在MVC应用程序框架中,开发人员不仅能够使用传统的Response.Redirect(页面)的方法进行页面重定向,MVC还支持直接返回重定向参数进行重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return Redirect("/Beta/Get");                                                                            //返回重定向参数

        }

上述代码通过使用重定向参数进行页面重定向。由于MVC编程模型是通过Controllers进行页面的呈现,而MVC编程模型同样是基于面向对象的,当用户访问某个路径实际上是访问相应的Controllers的方法。对于相同的页面而言,开发人员能够使用MVC编程模型中提供的RedirectToAction进行页面重定向,示例代码如下所示。

       public ActionResult Index()

        {

           return RedirectToAction("Get");                                                                      //通过方法重定向页面

        }

       public ActionResult Get()

        {

           return View();                                                                                                     //返回默认视图

        }

上述代码只能使用在同一个Controllers中,当需要跳转到不同的Controllers中时,同样可以通过此方法进行页面重定向,示例代码如下所示。

        public ActionResult Index()

        {

           return RedirectToAction("Login","Account");                                                //跨Controllers跳转

        }

上述代码同样使用RedirectToAction方法进行重定向,重载的RedirectToAction方法前一个参数是相应的页面的方法,而后一个参数是相应的页面所在的Controllers。

17.4.5  ASP.NETMVC URL路由(URLRouting)

在ASP.NET MVC编程模型中,除了M、V、C三个模块,MVC编程模型中最为重要的就是ASP.NET MVC URLRouting的概念。运行ASP.NET MVC应用程序,其URL如图17-23所示。

图17-23  ASP.NET MVC应用程序URL路径

从途中可以看出URL路径为http://localhost:2448/Home/About,从前面的小结中可以知道,当访问了该路径时,实际上是访问了HomeControllers.cs中的About方法,而About方法通过About.aspx页面进行视图呈现,视图中所使用的数据是在About方法中声明的ViewData,这样才组成了一个MVC应用程序页面。

ASP.NET MVC应用程序中实现上述过程,即将/Home/About映射到相应的Controllers的相应方法中就必须使用到ASP.NET MVC URLRouting,ASP.NET MVC URLRouting定义在Global.ascx文件中,Global.ascx文件代码如下所示。

namespace _17_1

{

    publicclass MvcApplication : System.Web.HttpApplication

    {

       public static void RegisterRoutes(RouteCollection routes)                                                 //注册路由

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

       protected void Application_Start()                                                                                            //应用程序执行

        {

           RegisterRoutes(RouteTable.Routes);                                                                              //实现方法

        }

    }

}

上述代码通过URLRouting实现了URL地址的映射,在Global.ascx中,最为重要的是RegisterRoutes方法,该方法实现了相应映射规则,示例代码如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                                                                  //注册路径

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}/{id}",                                                                                           //设置路由规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现路由规则

           );

        }

上述代码中使用了RouteCollection对象的MapRoute进行地址配置,其中为ASP.NET MVC应用程序URL的配置的规则为"{controller}/{action}/{id}",这也就是说其映射会按照controller名称、方法名称和ID进行映射,所以/Home/About路径就映射到了HomeControllers.cs中的About方法。在了解了基本的URLRouting实现URL地址映射后,开发人员能够修改相应的映射规则进行更改,更改后的规则如下所示。

       public static void RegisterRoutes(RouteCollection routes)

        {

           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(

               "Default",                                                                                                                       //设置默认名称

               "{controller}/{action}.html/{id}",                                                                                  //修改规则

               new { controller = "Home", action = "Index", id ="" }                                             //实现默认规则

           );

        }

上述代码在相应的规则中进行了修改,修改规则是访问相应的Controllers中的方法名称加.html进行页面访问,这样http://localhost:2448/Home/About就不能够进行访问,因为URL Routing规则进行了更改。如果要访问相应的页面,则必须访问http://localhost:2448/Home/About.html进行页面访问,运行后如图17-24所示。

图17-24  修改URL Routing

正如图17-24所示,在访问页面时,原有的页面再不能够进行访问,而必须通过访问/Home/About.html进行页面访问。

17.4.6  ASP.NETMVC控件辅助工具(Helper)

在ASP.NET MVC开发模型中,由于将页面进行分层开发和呈现,开发人员在视图开发中通常是不推荐使用服务器控件的,因为在ASP.NET MVC页面是派生自ViewPage而ASP.NET WebForm是派生自System.Web.UI.Page的,同样为了规范ASP.NET MVC开发模型中页面的呈现和运行,使用服务器控件也不是最好的选择。为了能够方便的呈现控件和进行URL操作,ASP.NET MVC开发模型提供了Helper进行控件的呈现和URL操作,Helper包括HtmlHelper和UrlHelper。

1.HTML辅助工具(HtmlHelper)

由于在ASP.NET MVC开发模型中不推荐使用服务器控件,这就会提高ASP.NET页面编程的复杂性,使用HtmlHelper能够减少相应的编程复杂性。使用HtmlHelper能够创建HTML控件并进行控件编程,在MVC编程模型中,其执行过程很像传统的ASP的执行过程。使用HtmlHelper创建HTML控件的代码如下所示。

    <h2>HtmlHelper</h2>

    <p>

        请输入用户名:<% =Html.TextBox("Name") %>                                                            //使用TextBox

    <br/>

        请输入密码:<% =Html.Password("Name") %>                                                             //使用Password

    <br/>

        <input id="Submit1"type="submit" value="submit" />

    </p>

上述代码通过HtmlHelper创建了HTML控件,HtmlHelper方法创建控件只能够在Views中使用而不能在Controllers中使用。上述代码运行后如图17-25所示。

图17-25  HtmlHelper创建的HTML控件

注意:这里的TextBox控件和Password控件并不是ASP.NET控件,TextBox控件和Password控件分别生成的是HTML控件。

2.URL辅助工具(UrlHelper)

UrlHelper在MVC开发框架中比较简单,UrlHelper是用来呈现相应的URL路径的,UrlHelper使用的示例代码如下所示。

    <h2>HtmlHelper</h2>

     <p>

        <%=Url.Action("Index","Beta")%>

     </p>

上述代码通过使用UrlHelper的Action方法进行URL的呈现,在Action方法中,其参数分别为方法名和Controller,上述代码中用于显示BetaController中的Index页面URL,运行后如图17-26所示。

图17-26  UrlHelper

17.4.7  ASP.NET MVC表单传值

ASP.NET的运行模型很像传统的ASP,在ASP.NET MVC开发模型中,由于无法使用runat=“server”进行表单传值,开发人员只能够自己编写表单进行传值。进行表单传值有两种方法,一种是编写from进行表单传值,一种是通过HtmlHelper进行表单生成和传值。编写form的表单传值方法示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<form id="form1"method="post"action="<%=Html.AttributeEncode(Url.Action("Html","Beta"))%>">

    请输入用户名:<% =Html.TextBox("Name") %>

   <br/>

    请输入密码:<% =Html.Password("Name") %>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index","Beta") %>

    <%=ViewData["p"] %>

</form></p>

上述代码通过传统的方法在HTML中编写from标签,而form标签的属性action需要通过使用HtmlHelper进行指定,这里指定的是BetaControllers中的Html方法进行参数传递处理。在Html方法中,可以通过编程实现相应的表单传值处理,示例代码如下所示。

       public ActionResult Html()

        {

           if (Request.HttpMethod != "POST")                                                                //判断传递方法是否为Post

           {

               ViewData["p"] = "表单还没被传递";                                                         //填充相应的ViewData

           }

           else

           {

               ViewData["p"] = "表单已被传递";                                                             //填充相应的ViewData

           }

           return View();                                                                                                     //返回视图

        }

上述代码首先会判断传递的方法是否为POST,如果为POST,说明表单已经传递,否则表单还没有传递,上述代码运行后如图17-27和图17-28所示。

 

图17-27  表单没传递               图17-28  表单已传递

当用户单击按钮控件时,就会进行表单的传递。在Html方法中,通过编程进行了表单传递后的操作。在MVC编程中,可以通过HttpMethod判断表单是否传递,如果传递表单,则可以通过编程的方法进行数据判断和数据操作等其他操作。在ASP.NET MVC中,还可以使用HttpHelper进行表单传值,示例代码如下所示。

<h2>HtmlHelper</h2>

<p>

<% using (Html.BeginForm("Html","Beta"))

   { %>

    请输入用户名:<% =Html.TextBox("Name")%>

   <br/>

    请输入密码:<% =Html.Password("Name")%>

   <br/>

   <input id="Submit1" type="submit"value="submit" />

   <%=Url.Action("Index", "Beta")%>

   <br/>

    <%=ViewData["p"]%>

<%} %>

</p>

在表单创建时,HttpHelper的BeginForm方法能够创建一个Form进行表单生成,BeginForm方法包括两个参数,第一个参数为方法,第二个参数为Controllers。当运行该页面时,BeginForm方法能够创建一个Form进行表单传值。

注意:使用BeginForm方法创建表单,而表单的结束并不是使用EndForm,使用BeginForm方法创建需要使用using{}的方法进行Form中内容容器。

当ASP.NET MVC应用程序能够进行表单传值后,就能够通过HttpMethod进行判断,如果用户进行了提交,开发人员能够通过编程实现数据更新的插入和删除等操作。在ASP.NET MVC应用程序中,其数据通常使用LINQ进行描述和操作,关于LINQ的知识会在后面专门讲解。

17.5  小结

本章讲解了ASP.NETMVC开发模型,以及工作原理,在创建ASP.NET MVC应用程序时,系统会自行创建若干文件和文件夹。ASP.NET MVC开发模型和ASP.NET Web Form极不相同,所以创建的文件夹和文件也不相同,要了解ASP.NET MVC开发模型就首先需要了解这些文件和文件夹的作用。本章还讲解了ASP.NET MVC的工作原理和工作流程,包括ASP.NET MVC中的Controllers、Model以及Views是如何形成一个完整的页面呈现在客户端浏览器中。本章还包括:

q  安装ASP.NET MVC:讲解了如何在Visual Studio 2008中安装ASP.NET MVC应用程序开发包进行ASP.NET MVC应用程序开发。

q  新建一个MVC应用程序:讲解了如何创建一个新的ASP.NET MVC进行应用程序开发。

q  ASP.NET MVC应用程序的结构:讲解了ASP.NET MVC应用程序的基本结构,以及ASP.NET MVC中M、V、C的概念。

q  创建ASP.NET MVC页面:讲解了如何创建ASP.NET MVC页面。

q  ASP.NET MVC ViewData:讲解了ASP.NET MVC中ViewData的作用和使用方法。

q  ASP.NET MVC TempData:讲解了ASP.NET MVC中TempData的作用和使用方法。

q  ASP.NET MVC页面重定向:讲解了ASP.NET MVC中页面重定向的方法。

q  ASP.NET MVC URLRouting:讲解了什么是ASP.NET MVC URLRouting,以及URLRouting基本原理。

q  ASP.NET MVC Helper:讲解了基本的ASP.NET MVC中HtmlHelper,以及UrlHelper的作用。

q  ASP.NET MVC表单传值:讲解了如何使用ASP.NET MVC应用程序的HtmlHelper,以及传统的HTML方式进行表单传值。

在ASP.NET MVC应用程序中,使用数据操作通常是使用LINQ进行数据操作的,当用户提交了表单,开发人员能够通过判断进行数据的相应操作,开发人员能够使用LINQ进行数据操作,有关LINQ的知识将在后面的章节讲解。

ASP.NET MVC

标签:

原文地址:http://blog.csdn.net/ym296900664/article/details/51701297

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!