`
yanyanquan
  • 浏览: 441496 次
  • 性别: Icon_minigender_1
  • 来自: 江门
社区版块
存档分类
最新评论

快速搞懂 ASP.NET MVC

阅读更多

有一只企鹅首先发现地球暖化、冰山在融化,回来告诉其它企鹅,却没有任一只企鹅愿意相信;因为企鹅们觉得现在生活过得很好,都不想费心思考如何改变、改变何时会来临,因此仍每天做例行性的工作,不愿去研究别人的观点。「有时人们会抗拒改变,其实只是不想改变;但是愿意接收新观念的技术人员,通常会活得比较久」。本帖只提供 MVC Pattern 的观念和架构介绍,仅供未接触过 MVC Framework 的 .NET 技术人员作为参考之用,以评估是否要深入学习或在将来的项目导入。


常在网络上,看到有网友误认 MVC 和 3-Tier (三层架构) 是类似的东西:
http://topic.csdn.net/u/20090405/21/97a137ff-2105-4117-a0c3-39d7f0f1c952.html
http://topic.csdn.net/u/20090415/13/9ebe5011-c56b-47e6-9f89-40b70896a041.html

但二者本质上是完全不同的概念,如下:

3-Tier 或 N-Tier 的架构,中间层可能包含 EJB, Enterprise JavaBeans (J2EE),或 .NET Enterprise Services、Remoting、WCF:
Client (WebPage) -- [ BLL (业务逻辑层) -- DAL (数据访问层) ] (Web Server) -- 数据来源或数据库
Client (WebPage) -- [ BLL (业务逻辑层) -- DAL (数据访问层) ] (Web Server + Application Server) -- 数据来源或数据库

MVC 则为:
Model (模型) - 包含 BLL、DAL。View 和 Controller 都依赖于 Model,但是 Model 既不依赖于 View,也不依赖于 Controller,这是分离的主要优点之一
View (视图) - 仅负责生成输出 (UI)。以 ASP.NET MVC 来说,不再有 Code-behind 这种 .aspx.cs 文件,亦无 runat="server" 标记、form 标记、控件声明、事件处理
Controller (控制器) - 控制整个系统的 workflow、运作逻辑、错误处理、身分验证和授权、用户输入数据验证、…等等


总的来讲,微软的 ASP.NET MVC Framework 是为了让 ASP.NET 更适合中、大型的项目,能统一规划、控管整个网站系统的流程 (用 Controller 处理),并更有效地分工开发、日后维护 (避免许多 WebForm 里重复出现相同功能的自定义函数)、管控某个功能在修改后对系统整体的影响,并将不同的功能作更明确地切割,让不同专长的技术人员各司其职,也顺便提高了代码的可读性,便于测试 (TDD, test -driven development) (减少直接绑到用户界面中的代码量) [4],并达到「松散耦合 (loosely coupled)」,让组件易于更换和重复使用。但也因此,ASP.NET 程序员必须先改变过去,把很多业务逻辑、输入验证、页面切换…等杂七杂八的功能,全部写在 Code-Behind (aspx.cs) 里的旧习惯。

ASP.NET MVC provides a framework that enables you to easily implement the model-view-controller (MVC) pattern for Web applications. This pattern lets you separate applications into loosely coupled, pluggable components for application design, processing logic, and display. ASP.NET MVC also greatly facilitates test -driven development (TDD).


事实上,MVC Pattern 的发明已有二十多年,其与再衍生的观念和框架 (MVP),在 Java / J2EE / Struts 的一些 Framework 早已行之多年。MVC 模式的结构如下 [4]:

View (JSP) 只纯粹用来生成输出,不涉及数据来源的访问、事件处理、各种逻辑处理和运算工作。因此更适合大型项目的分工,把这层完全交由美工人员制作 (而非程序员兼美工和排版)。此层如同 ASP.NET 中的 .aspx 前台页面,亦即 UI (User Interface)。

Model (JavaBean、EJB 组件) 用来存放独立且可重复使用的组件,包括:数据来源 (数据库) 的访问、商业逻辑的代码,并应与 View 作完整地切割,以便保留系统日后扩充或改写时的弹性。此层如同 ASP.NET 中的 App_Code 文件夹中的自定义类、DataSet (.xsd)、TableAdapter、…等等。

Controller (Java Servlet) 用来控制整个网站处理的「流程」,负责协调 View 和 Model 之间的流程传递和转向,也要管理和指派由哪个文件去接收用户所提出的「请求 (request)」,亦即由它决定要展现哪一个 aspx 文件给用户。当用户从浏览器送出 request 时 (例若用鼠标单击页面中的控件,或输入数据后单击 Button 的提交、输入 URL 网址、点选 hyperlink…等等),Controller 里定义的某些 method 会判断要交由 Model 中的哪些运算逻辑去处理,然后再判断要将处理结果传回哪一个 View 去显示出来。此外,Controller 还可包含错误处理、授权、输入验证…等功能的代码,集中统一处理,以避免传统 WebForm 里大量重复的代码。但说穿了,Controller 事实上只是一个自定义类,搭配一些 Attribute (特性)。而 Controller 也是目前 ASP.NET 所欠缺的部分。

 


图 1 MVC (Model 2) 架构的运作方式,可与下图 2 的 ASP.NET MVC 项目相互对应


事实上,在 Java / JSP / JavaEE 常引用的网站开发架构中,还可分为 Model 1 与 Model 2。而 Model 1 还可分为二至三种,如下:

● 第一种是将 HTML 和 .NET (Java) code 混在一起,俗称意大利面的写法,如:古早的 ASP。这种 Inline code 最为人垢病的问题,是代码的可读性低、难以维护。

● 第二种是由与 .aspx 一对一搭配的 Code-Behind code (.aspx.cs) 直接访问数据库,亦即二层式的架构。但这样的缺点是代码难以重复使用,而且因为逻辑已写死在固定的页面里,会造成系统日后扩充、维护的困难。

● 第三种是经由自定义类库、App_Code 文件夹中的自定义类或组件,去访问数据库,或做商业逻辑的运算 (JSP + JavaBean)。但此种做法仍缺乏「流程 (flow)」的统一控管,导致每一支 ASPX (JSP) 都要验证用户身份、验证 request 的参数、处理 Session、做例外处理,甚至包括 View 里的写码原则、语系设定,都得在每一支 ASPX 对应的 Code-Behind 去处理,也因此不适合大型系统的开发、扩充和维护。这种架构虽然也能做到虚拟式的三层式或多层式架构,但也是目前 ASP.NET 的极限。


至于 Model 2,即俗称的 MVC Pattern,则加入了 Controller 的部分,将流程及事件交由中心控管,除了可让整个系统的运作流程更为明确,有效切开各层的工作,亦可避免让 View 里的 Code-Behind 去处理 Model 中的数据库访问、商业逻辑运算,也不必再每个页面重复撰写「流程传递和转向」的代码,而改由中央的 Controller 程序代码 (action method) 来统一控管。

但 MVC 架构也有其缺点,例如开发人员需要另外花时间转换观念及学习某一个 Framework,尤其是 .NET 的开发人员,因为过去较没有 Controller 统一协调流程的观念,势必得重新习惯,将很多原本写死在各个页面中的代码,统一改写在 Controller 里面。而且系统在设计阶段时,即要先协调好各个类及对象,彼此间数据交换的格式及做法,因此势必得拉长系统事先的分析、规划时程。但若能有像 Java Struts 或 ASP.NET MVC Framework 这样现成的框架可套用,则日后开发大型系统时,即可望达到事半功倍的效果。


要开发 ASP.NET MVC,必须要有 Visual Studio 2008 + SP1,并下载 MVC 套件 (经过至少两年的研发,微软终于在 2009 年 4 月发布了 1.0 正式版),下载网址如下:
ASP.NET MVC 1.0 download (2009/04/09):
http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&displaylang=en

安装完成后,在新建项目时,会多出一个「ASP.NET MVC Web Application」的选项。创建一个默认的 MVC 项目后,其在 VS 解决方案的结构如下图所示:


图 2 View 中的 ASPX、ASCX、MasterPage 纯粹负责显示用,默认没有配置 Code-Behind 文件 (aspx.cs)


如上图 2,ASP.NET MVC 项目,会自动产生存储 MVC 文件的三个文件夹、控制流程的两个 Controller 类、多个没有 Code-Behind 的 View 页面,和定义 Routing rules 的 Global.asax.cs。

事实上版工我在一年前试玩 ASP.NET MVC Beta 版时,当时的 View 默认仍配有 Code-Behind 文件,但里面空无一物,只有一行注释:
!-- Please do not delete this file. It is used to ensure that ASP.NET MVC is activated by IIS when a user makes a "/" request to the server. --

在前阵子发布的正式版里,View 默认已不配置 Code-Behind 文件。此外,ASP.NET MVC 里的 View,为了让项目开发更明确地切割,已不再有页面初始化和加载方法,也没有事件处理程序,除了基类声明以外没有任何内容,基类声明为 System.Web.Mvc.ViewPage,而不再是过去 WebForm 的 System.Web.UI.Page。


新创的 ASP.NET MVC 项目,直接按 F5 即可执行,如下图 3 所示。但由于 MVC 的 View 会在显示前先要求 Controller 运行 (参考图 1),因此若您尝试将 View 里的某个 .aspx 设为「起始页」后,按 F5 执行时,反而会发生「HTTP 404. The resource cannot be found.」的错误,亦即若想直接导航至该页面将不起作用。


图 3 ASP.NET MVC 项目的首页


您会发现浏览器里的 URL 会像下面这样,网址不是具体的 .aspx 扩展名:

http://localhost:端口号/Home/index
http://localhost:端口号

事实上该页的内容,是去捉 Views/Home 文件夹底下,的 Index.aspx 的内容来呈现。其由 Global.asax.cs 配置,并用了「URL 重写 (Url Routing)」,让用户可以按你自己定义的的规则来访问网站 [14]。

在图 3 首页的右侧,会有两个 hyperlink,可分别导向「LogOn.aspx」、「About.aspx」页面;但 hyperlink 要导向哪一个页面,不是写死在 View 的页面中 (已无 Code-Behind),而是统一由 Global.asax.cs 去定义 Routing rules,去解析当浏览器收到 URL、表单或任何 request 时,应该要扔给哪一个 Controller 自定义类去处理;再由该个被指定的 Controller (如上图 2 里默认自动产生的 HomeController.cs),里面所定义的一或多个 System.Web.Mvc.ActionResult 类,以及 View 方法 (术语叫 action method),去设定要把 UI render 回哪一个 View (页面) 去,也就是本文一开始所提到的 (参考本帖图 1),Model 2 架构是由 Controller 文件,去统一控管整个 ASP.NET 系统的流程、页面导向,而不是写死在各个 aspx.cs 文件里。


以下为 Global.asax.cs 的一部分代码,网友们可搭配参考上图 2 里 Controller、View 的结构去阅读:

using System.Web.Mvc;
using System.Web.Routing;

public class MvcApplication : System.Web.HttpApplication
{
    
public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute(
"{resource}.axd/{*pathInfo}");

        
// C# 3.0 的「匿名类型 (Anonymous Type)」语法
        routes.MapRoute(
            
"Default",                      // Route name
            "{controller}/{action}/{id}",   // URL with parameters (控制器名 / 操作名称 / ID 参数)
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    }
}

 

MapRoute 方法里的三个参数,分别代表:routes、route name、URL。其中第一个参数 "Default",代表了项目中的 Default.aspx (不是位于 View 文件夹里)。这个 URL Routing 是为了解决用户直接访问域名时,会出现找不到文件的情形,所以要采用这个方法,将主页改成 Routing 到 Home/Index 上。因此当您在浏览器的地址栏输入:

http://localhost:端口号/Default.aspx

http://localhost:端口号

亦会导至图 2 中的 Views/Home/Index.aspx。


System.Web.Mvc Namespace (MSDN Library, 暂无中文版):
http://msdn.microsoft.com/en-us/library/system.web.mvc.aspx

RouteCollectionExtensions.MapRoute Method:
http://msdn.microsoft.com/en-us/library/dd470521.aspx

ASP.NET MVC Framework (Part 1) (ScottGu 于 2007 年 11 月发表的 blog,图中为 ASP.NET MVC 在 Beta 版时的画面):
http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx


在图 3 的首页里,当鼠标移到右侧的 hyperlink 时,实际连结的页面名称 (某个 .aspx) 并不会直接显示在浏览器的地址栏、浏览器下方的信息栏里,因为 request「转向」的运作皆统一由 Controller 处理,亦即由图 2 中 HomeController.cs 里,配置的 System.Web.Mvc.ActionResult 类的 actionName 去指定,因此浏览器的网址仍会维持 Site.Master (MasterPage) 里的 Html.ActionLink 绑定,所配置的 actionName (即下方两行代码的第二个参数 "Index"、"About"),而不会如过去 ASP.NET 1.x / 2.0 般,直接在地址栏里,显示某一个 .aspx 的页面名称。

以下为 Site.master 的一部分代码:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<ul id="menu"> 
    
<li><%= Html.ActionLink("Home""Index""Home")%></li>
    
<li><%= Html.ActionLink("About""About""Home")%></li>
</ul>

 

Controller 除了用来控管整个网站的流程转向外,事实上还能避免大量的代码重复,亦即统一处理一些系统可「共享」的功能,例如:验证用户身份、输入验证 (validate)、Session 管理,或是像购物网站中,当购物车里物品的添加、修改、移除时,任何用户皆相同的「共通逻辑」处理;以及要结帐时,去做购物数量、单价相乘的计算动作,或将某个存储购物明细的 Collection 数据结构对象加入 Session,最后再转向某一个页面 (View)。

 

总结:

本帖仅是给 .NET 技术人员,作为初步了解 MVC Pattern,以及 ASP.NET MVC Framework 的入门文章。若有兴趣深入研究的网友,可参考本帖最下方的「相关文件」,另博客园及网络上已有许多相关的帖子。至于通用的 MVC 观念,亦可参考坊间 JSP / Struts / J2EE 的网络论坛、相关书籍,或 Design Patterns (设计模式) 中的「复合模式 (Compound Pattern)」[15]。

如同 MSDN Magazine 中提到的 [7],ASP.NET MVC 不是用来取代传统 ASP.NET WebForm 的,两者有各自的优点和缺点,而将来的 ASP.NET MVC 还可能在 UI、控件拖曳、Routing 上持续改进。不过身为一个技术人员,最好能早点厘清两者的特性与优缺点 [4] [6],以评估是否要深入学习,或在将来的项目导入;并思考为什么微软要推出这个框架,且还花了至少两年的时间很慎重地去研发。

 

--------------------------------------------------------

相关文件:

[1] MVC : The Official Microsoft ASP.NET Site:
http://www.asp.net/mvc/
http://www.asp.net/learn/mvc/
http://www.asp.net/learn/mvc/tutorial-01-cs.aspx
http://www.asp.net/learn/mvc/tutorial-02-cs.aspx
http://www.asp.net/learn/mvc/tutorial-03-cs.aspx

http://www.asp.net/learn/mvc/tutorial-38-cs.aspx
http://www.asp.net/learn/mvc-videos/
http://forums.asp.net/1146.aspx

[2] ASP.NET - Home:
http://aspnet.codeplex.com/Wiki/View.aspx?title=MVC

[3] ScottGu's Blog (美国微软开发部门总经理):
http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx

[4] Model-View-Controller (MSDN):
http://msdn.microsoft.com/en-us/library/ms978748.aspx (英文)
http://msdn.microsoft.com/zh-cn/library/ms978748.aspx (中文)

[5] Page Controller (MSDN):
http://msdn.microsoft.com/en-us/library/ms978764.aspx
http://msdn.microsoft.com/zh-cn/library/ms978764.aspx

[6] Implementing Model-View-Controller in ASP.NET (MSDN):
http://msdn.microsoft.com/en-us/library/ms998540.aspx
http://msdn.microsoft.com/zh-cn/library/ms998540.aspx

[7] Building Web Apps without Web Forms (MSDN Magazine):
http://msdn.microsoft.com/en-us/magazine/cc337884.aspx
http://msdn.microsoft.com/zh-cn/magazine/cc337884.aspx

[8] 从零开始学习 ASP.NET MVC 1.0 (一) 开天辟地入门篇 (子秋的博客):
http://www.cnblogs.com/zhangziqiu/archive/2009/02/27/ASPNET-MVC-1.html

[9] ASP.NET MVC Framework 与 WCSF 中 MVP 模式之小小比较 (Terry Lee):
http://www.cnblogs.com/Terrylee/archive/2008/01/01/aspnet-mvc-framework-vs-wcsf-mvp.html
ASP.NET MVC Framework 体验(1):从一个简单实例开始 (Terrylee):
http://www.cnblogs.com/Terrylee/archive/2007/12/11/aspnet-mvc-framework-overview.html

[10] 博客园 ASP.NET MVC 技术专题:
http://kb.cnblogs.com/zt/mvc/

[11] 一步一步学习 ASP.NET MVC 1.0 创建 NerdDinner 范例程序:
http://blog.entlib.com/entlibforum/archive/2009/03/28/asp.net-mvc-1.0nerddinner-part-1.aspx

[12] ASP.NET MVC 开发心得分享 (1):开发流程篇 (繁体中文):
http://blog.miniasp.com/post/2009/01/ASPNET-MVC-Developer-Note-Part-1.aspx
ASP.NET MVC 开发心得分享 (2):与原始码共舞 (繁体中文):
http://blog.miniasp.com/post/2009/02/ASPNET-MVC-Developer-Note-Part-2.aspx
研究 Oxite 这套 CMS 系统吧!(繁体中文):
http://blog.miniasp.com/post/2008/12/Microsoft-Open-Source-content-management-system-Oxite-using-ASPNET-MVC.aspx

[13] .NET Framework Class Library:
System.Web.Mvc Namespace (暂无中文版):
http://msdn.microsoft.com/en-us/library/system.web.mvc.aspx

[14] URL Routing:
http://blog.csdn.net/chsword/archive/2008/03/11/2165866.aspx
http://www.cnblogs.com/terrylee/archive/2007/12/16/aspnet-mvc-framework-url-routing.html
http://www.cnblogs.com/qleelulu/archive/2008/03/17/1109893.html

--------------------------------------------------------

相关书籍:

[15] Head First 设计模式, Chapter 12:
http://www.dearbook.com.cn/book/213719
http://www.china-pub.com/36020

[16] Free ASP.NET MVC eBook Tutorial:
http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx

[17] ASP.NET MVC in Action:
http://www.manning.com/palermo/

[18] Pro ASP.NET MVC Framework:
http://www.apress.com/book/view/1430210079

[19] Professional ASP.NET MVC 1.0:
http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-1-0.productCd-0470384611.html

分享到:
评论

相关推荐

    ASP.NET MVC企业实战源代码Chapter12.rar

    本书共分为12章,以符合初学者思维的方式系统地介绍ASP.NET MVC的应用技巧,并结合实际项目详细地介绍如何基于ASP.NET MVC构建企业项目。通过本书的学习,读者可以全面掌握ASP.NET MVC的开发,并从代码中获取软件...

    Asp.Net MVC案例教程

    Asp.Net MVC案例教程 Asp.Net MVC案例教程 Asp.Net MVC案例教程 Asp.Net MVC案例教程 Asp.Net MVC案例教程 Asp.Net MVC案例教程

    asp.net MVC4 CMS

    asp.net MVC4 CMS 完整的源代码,学习和提高asp.net mvc4可以参考一下。

    ASP.NET MVC项目实例

    ASP.NET MVC作为微软官方的.NET平台下MVC解决方案,自诞生起就吸引了众多.NET平台开发人员的眼球。ASP.NET MVC从一开始的设计思路就与Struts不同,它的映射是利用路由配置而非xml,从而大大降低了开发复杂度,并且比...

    ASP.net MVC3 中文教程

    ASP.net MVC3 中文教程ASP.net MVC3 中文教程ASP.net MVC3 中文教程ASP.net MVC3 中文教程

    Pro ASP.NET MVC 5 Platform(Apress,Adam.Freeman,2014)

    The power of ASP.NET MVC 5 stems from the underlying ASP.NET platform. To make your ASP.NET MVC applications the best they can be, you need to fully understand the platform features and know how they ...

    ASP.NET MVC 5入门指南(中文PDF+源码)

    ASP.NET MVC 5入门指南 (中文PDF+源碼) 1. ASP.NET MVC 5 - 开始MVC 5之旅 2. ASP.NET MVC 5 - 控制器 3. ASP.NET MVC 5 - 视图 4. ASP.NET MVC 5 - 将数据从控制器传递给视图 5. ASP.NET MVC 5 - 添加一个模型 6. ...

    AngularJS开发ASP.NET MVC

    AngularJS 开发 ASP.NET MVC.

    ASP.NET MVC 4高级编程(第4版)清晰完整PDF版

    MVC专家“梦之队”对ASP.NET MVC 4的全新诠释 由Microsoft专家和极受敬重的软件开发社区负责人撰写的《ASP.NET MVC 4高级编程(第4版)》将带您学习最前沿的Web框架:ASP.NET MVC 4。本书开篇简要介绍ASP.NET MVC框架...

    Pro ASP.NET MVC 5 (精通ASP.NET MVC5框架) 中文+英文+配套源代码

    Pro ASP.NET MVC 5 (精通ASP.NET MVC5框架) 中文+英文+配套源代码

    [ASP.NET MVC] ASP.NET MVC 4 实战 (英文版)

    ASP.NET MVC 4 in Action is a hands-on guide that shows you how to apply ASP.NET MVC effectively. After a high-speed ramp up, this thoroughly revised new edition explores each key topic with a self-...

    【免费】ASP.NET MVC5 高级编程[附源码].rar

    ASP.NET MVC5高级编程(第5版.NET开发经典名著)作为Microsoft备受欢迎的MVC技术的最新版本,MVC 5是一个成熟的Web应用程序框架,支持快速的、TDD友好的开发。MVC允许开发人员创建动态的、数据驱动的网站。这样的...

    asp.net mvc 弹出窗口 技巧

    asp.net mvc 弹出窗口 技巧asp.net mvc 弹出窗口 技巧asp.net mvc 弹出窗口 技巧asp.net mvc 弹出窗口 技巧

    dwz框架 asp.net mvc3

    dwz框架 asp.net mvc3;dwz框架 asp.net mvc3;dwz框架 asp.net mvc3

    ASP.NET MVC5 官网下载源码.rar

    ASP.NET MVC5 官网下载源码.rar ASP.NET MVC5 官网下载源码.rar ASP.NET MVC5 官网下载源码.rar ASP.NET MVC5 官网下载源码.rar ASP.NET MVC5 官网下载源码.rar ASP.NET MVC5 官网下载源码.rar

    ASP.NET MVC5

    ASP.NET MVC5 高清完整版,适合新手学习,理解MVC架构

    [ASP.NET MVC] ASP.NET MVC with Entity Framework and CSS (英文版)

    [Apress] ASP.NET MVC with Entity Framework and CSS (英文版) [Apress] ASP.NET MVC with Entity Framework and CSS (E-Book) ☆ 图书概要:☆ This book will teach readers how to build and deploy a fully ...

    ASP.NET MVC 4高级编程 第4版PDF.rar

    ASP.NET MVC 是微软官方提出的一种Web开发框架,通过M是模型(model)-V视图(view)-C控制器(controller)l来设计创建Web应用程序。截至目前最新版本是MVC5,相对于之前的版本MVC5其可扩展性、易用性等方面都不很大的...

    Asp.Net mvc 3

    Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3,Asp.Net mvc 3

    asp.net mvc后台管理系统 数据库

    asp.net mvc后台管理系统 数据库

Global site tag (gtag.js) - Google Analytics