MVC(模型—视图—控制器)结构模式把一个应用程序拆分成三个主要组件:模型、视图和控制器。在创建基于MVC框架的Web应用程序时,你可以把ASP.NET MVC框架作为ASP.NET Web表单模式方案的一种重要候选。较之于基于Web表单的应用程序,ASP.NET MVC框架是一个轻量级的、测试性强的描述框架,它能够与现有ASP.NET特征(例如母版页面和基于成员身份的认证)紧密集成。MVC框架定义于System.Web.Mvc命名空间中。
长时间以来,MVC是一种为众多开发人员所熟悉的标准设计模式。一些类型的Web应用程序受益于MVC框架,而另一些将继续使用基于Web表单与回寄技术的传统型ASP.NET应用程序模式,还有一些类型的Web应用程序则有可能把这两种模式结合到一起使用。总之,MVC框架方案与Web表单方案并非相互排斥的。
总体来看,MVC框架包括下列组件:
(一)模型。模型对象是实现应用程序数据域逻辑的部分。经常情况下,模型对象还负责从数据库中检索和存储模型状态。例如,一个产品对象有可能从一个数据库中检索信息,操作其中的数据,然后把更新信息写回SQL Server数据库中的某一个产品表格内。
【提示】在小型应用程序中,模型经常是一个概念上的分离而不是一个物理概念。例如,如果应用程序仅读取一个数据集并且要把它发送到视图中,那么应用程序就不必专门创建一个物理模型层和相关联的类。在这种情况下,数据就直接承担了一个模型对象的角色。
(二)视图。视图是负责显示应用程序的用户接口(UI)的组件。典型情况下,这个UI是基于模型数据创建的。一个典型的示例就是一个产品表格的编辑视图。在此视图中,可以基于一个产品对象的当前状态显示文本框、下拉列表框和复选框等控件。
(三)控制器。控制器组件的作用是负责处理用户交互,操作模型,并且最终选择一个要显示UI的视图并生成之。在一个MVC应用程序中,视图仅仅负责显示信息,而由控制器负责处理和响应用户输入与交互。例如,由控制器来处理查询字符串值,并且把这些值传递到模型,然后在模型中使用该值进行数据库查询。
MVC模式在帮助你把应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离开来的同时,提供了这些元素之间的松耦合。MVC模式要求每一种不同的逻辑应该存在于应用程序中的特定位置。例如,UI逻辑隶属于视图,而输入逻辑隶属于控制器,业务逻辑则隶属于模型。这种分离有助于你在构建一个应用程序管理复杂性,因为它能够使你在某一时刻仅专注于实现的一个方面。例如,你可以专注于视图而不去关心业务逻辑。
除了管理复杂性外,较于测试一个传统型ASP.NET Web应用程序,基于MVC模式进行开发使得测试应用程序更加容易。例如,在一个传统型ASP.NET Web应用程序中,单个的类既用于显示输出也用于响应用户输入。因此,为传统型ASP.NET应用程序编写自动化测试可能非常复杂,因为为了测试单个页面,你必须实例化页面类,它所有的子控件以及应用程序中的其他依赖类。总之,你需要实例化大量的类才能够运行该页面,所以这种情况下要比针对应用程序的单个部件编写测试困难得多。于是,针对传统型ASP.NET应用程序的测试很可能比实现一个使用MVC框架开发的应用程序的测试要复杂和艰难得多。而且,一个传统型ASP.NET应用程序在测试时还需要使用一个Web服务器。相比之下,MVC框架把组件分离开来并且大量地使用接口,这使得有可能独立于框架的其他部分而较容易地单独测试单个组件。
此外,一个MVC应用程序的三个主要组件之间的松耦合特征还推动了平行开发。例如,一名开发人员可以开发视图,而另一名开发人员则在开发控制器逻辑,第三名程序员则可以专注于模型部分的业务逻辑的开发。
基于MVC框架Web应用程序的优点
归纳来看,ASP.NET MVC框架主要提供了下列优点:
通过把一个应用程序分离成相互独立的模型、视图和控制器三部分而进一步提高了应用程序复杂性的管理。
不再使用视图状态或基于服务器的表单技术。这使得MVC框架特别有利于想全面控制一个应用程序的行为的开发人员。
使用一种前端控制器(Front Controller)模式并通过单一的控制器来处理Web应用程序请求。这一特征使你有可能设计出一个支持极其丰富的路由基础结构的应用程序。有关于前端控制器的更多的信息,请参考http://go.microsoft.com/fwlink/?LinkId=106357。
提供对于测试驱动开发(TDD)的大力支持。
基于Web表单Web应用程序的优点
传统型基于Web表单的框架能够提供下列优点:
支持事件模型。此模型能够保留HTTP传输过程中的状态,而这十分有利于在线业务式Web应用程序的开发。基于Web表单的应用程序提供大量的事件,所有这些事件都得到数以百计的服务器控件的支持。
使用一种页面控制器(Page Controller)模式,此模式能够把许多功能添加到单个的页面。有关于页面控制器的更多的信息,请参考http://msdn.microsoft.com/zh-cn/library/ms978764.aspx。
使用视图状态或基于服务器的表单,这使得状态信息管理更加容易。
ASP.NET MVC框架特征
概括来看,ASP.NET MVC框架大致提供了下列重要特征:
实现应用程序基本任务(输入逻辑,业务逻辑和UI逻辑)的分离,支持测试及测试驱动开发(TDD)。MVC框架中所有的核心契约都是基于接口的,因此十分利于使用mock对象(这是一些模拟应用程序中实际对象的模拟对象)测试工程。你可以对应用程序进行单元测试而不必在真正的ASP.NET进程中运行控制器,这加快了单元测试的速度和灵活性。你可以使用与.NET框架相兼容的任何单元测试框架测试你的工程。
提供了一个可扩展的和可插接的框架。ASP.NET MVC框架组件的设计支持用户十分容易地对它们进行替换或定制。你可以设计并加入你自己的视图引擎,URL路由策略,行为方法参数串行化,以及其它组件。ASP.NET MVC框架还支持使用现有依赖性注入(即“Dependency Injection”,简称“DI”)和控制反转(IOC)容器模型。其中,DI允许你把对象注入到一个类中,而不是依赖于类去创建对象本身。而IOC指定,如果一个对象要求使用另一个对象,那么第一个对象应该从一个外部源(例如一个配置文件)得到第二个对象。这一支持极有利于对工程的测试。
实现了一个强有力的URL映射组件,支持你在应用程序中构建易于理解的可搜索的URL(而不是像诸多Web应用URL中的那种极其复杂的表达方式)。如今,URL中不必包括文件扩展名,而且其设计还支持URL命名模式。因此,这种模式有利于搜索引擎优化(SEO)和REST(表述性状态转移)寻址。
支持在现有ASP.NET页面(.aspx文件)、用户控件(.ascx文件)以及母版页面(.master文件)标记文件中把标记用作视图模板。你可以在使用ASP.NET MVC框架的过程中继续使用现有ASP.NET特征,例如嵌套的母版页面,内联表达式(<%=%>),声明性服务器控件,模板,数据绑定,本地化,等等。
支持现有ASP.NET特征。ASP.NET MVC框架支持你使用例如表单和Windows认证,URL授权,会员和角色,输出缓冲和数据缓冲,会话和配置状态管理,健康监视,配置系统,提供者架构,以及其它ASP.NET特征。
URL映射
典型情况下,在一个ASP.NET网站中,URL会被映射到存储在磁盘上的文件(主要是指.aspx文件)。这些.aspx文件中将包括针对客户端发出的请求要处理的代码或标记。
ASP.NET MVC框架以不同于ASP.NET网站应用程序的方式把URL映射到服务器代码。MVC框架不是把URL映射到ASP.NET页面或HTTP处理器程序,而是直接把URL映射到特定的控制器类。然后,由控制器类负责处理发来的请求,例如用户输入与交互,以及基于用户输入执行适当的应用程序及数据逻辑。典型地,一个控制器类调用一个单独的视图组件来生成相应的HTML输出作为对客户端发出请求的响应。
在ASP.NET MVC框架中,模型、视图和控制器组件被分离开来。典型地,模型组件主要负责维护数据库中持久数据的状态,而视图组件则由控制器进行选择并最终在客户端生成相应的UI。默认情况下,ASP.NET MVC框架使用现有ASP.NET页面(.aspx),母版页面(.master)和用户控件(.ascx)类型作为在浏览器端的输出形式。控制器组件将定位控制器中适当的行为方法,取得用作行为方法的参数值,处理执行行为期间所有可能发生的错误,并生成要求的视图。每一组组件各自存在于一个MVC Web应用程序工程的一个单独的文件夹下。
通过提供了一个URL映射引擎,ASP.NET MVC框架在把映射URL到控制器类方面提供了相当的灵活性。你可以使用这种映射引擎来定义路由规则,然后ASP.NET MVC框架使用这些路由规则来计算发来的URL请求并选择要执行的控制器。你还可以让路由引擎自动地分析URL中定义的变量并且使ASP.NET MVC框架把这些内容以参数方式传递给控制器。
MVC框架与页面回寄
ASP.NET MVC框架并不使用传统的ASP.NET回寄模型来实现与服务器端的交互。代之的是,所有的终端用户交互都被路由到一个控制器类。这有利于保持UI逻辑和业务逻辑的分离,并且有助于测试目的。结果是,ASP.NET视图状态和ASP.NET页面生命周期事件并没有与基于MVC的视图集成到一起。