• 摘要:MVC是一种架构设计模式,该模式主要应用于图形化用户界面(GUI)应用程序。那么什么是MVC?MVC由三部分组成:Model(模型)、View(视图)及Controller(控制器)。

MVC概念

MVC是一种架构设计模式,该模式主要应用于图形化用户界面(GUI)应用程序。那么什么是MVC?MVC由三部分组成:Model(模型)、View(视图)及Controller(控制器)。

Model即应用程序的数据模型。任何应用程序都离不开数据,数据可以存储在数据库中、磁盘文件中,甚至内存中。Model就是对这些数据的抽象,不论数据采取何种存储形式,应用程序总是能够通过Model来对数据进行操作,而不必关心数据的存储形式。数据实体类就是常用的一种Model。例如,一个客户管理应用程序使用数据库来存储客户数据,数据库表中有一个客户表Customer,相应的程序中一般会建立一个数据实体类Customer来与之对应,这个实体类即使客户表的Model。

View是应用程序的界面。用户通过View来操作应用程序,完成与程序的交互。View提供了可视化的界面来显示Model中定义的数据,用户通过View来操作数据,并将对Model数据操作的结果返回给用户。在桌面应用程序中,View可能是一个或多个Windows窗体。在Web应用程序中,View是由一系列网页构成,在ASP.NET网站中即为.aspx页面。

Controller 定义了程序的应用逻辑。用户通过View发送操作命令给Controller,由Controller按照程序设计的逻辑来更新Model定义的数据,并将操作结果通过View返回给用户。

MVC的历史

MVC这一概念最早由美国教授Trygve Reenskaug于1979年提出。1988年MVC这一设计模式正式在《A Cookbook for Using the Model-View-Controller User Interface Paradigm in Smalltalk -80》一书中提出。伴随着微软Windows操作系统的迅速发展与普及,图形化用户界面应用程序逐渐成为主流,很多编程语言都出现了MVC框架,以方便开发人员使用该模式来设计应用程序。这些框架中大部分都是针对Web应用程序。

.NET Web开发中MVC设计模式的实现

ASP.NET 1.x中使用了CodeBehind技术,彻底终结了传统ASP程序开发的梦魇:程序逻辑与HTML界面元素混杂在一起。CodeBehind技术将代表程序界面(View)的.aspx文件与逻辑(Controller)代码.vb/.cs文件的分离即是一种MVC式的设计。ASP.NET 2.0中又出现了CodeBeside技术,即一个.aspx文件可以有多个.vb/.cs文件,这又方便了界面与逻辑代码的进一步分离。

2008年3月微软发布了针对ASP.NET 3.5 的MVC框架 (Preview 2 版本)。这是一个真正意义上的ASP.NET MVC框架。该框架可以说是对之前为开发人员所熟悉的基于Web Form的应用程序开发方式的"颠覆"。变化可谓"震撼":

1. 使用URL Routing技术:Web程序的URL不再是指向具体的物理页面.aspx,而是指向某个Controller的某个方法。一个典型的MVC架构的程序,其URL可能如下所示:

http://www.mysite.com/Customer/Index

使用该MVC架构的程序其URL不必有文件扩展名。上面这个URL中的Customer即为Controller的名字。而Index是Customer定义的一个方法名。

2. Web程序的界面.aspx不再使用服务器端的Form:

<asp: form runat="server"></form>

那么与服务器端的Form相关的Postback以及页面生命周期的事件也不存在了。

3. 页面中不再有View State。MVC下将不能使用View State来存储程序状态信息。

4. 不再提供依赖于服务器端Form的服务器控件事件,开发人员熟悉的Button_Clicked事件在MVC下将不再需要。

    NET MVC示例

安装完 ASP.NET MVC Preview 2后,VS2008中会添加一个新的项目模板"ASP.NET MVC Web Application", 如下图所示

新建该项目后, VS2008自动生成项目的文件结构如下, MVC三个组成部分各有一个文件夹来存储各自的程序文件。

前面提到的URL Routing即在Global.asax.cs中设置:

public class GlobalApplication : System.Web.HttpApplication

{

public static void RegisterRoutes(RouteCollection routes)

{

// 注意: IIS7以下的IIS版本需将URL格式设置为 "{controller}.mvc/{action}/{id}" to enable

routes.Add(new Route("{controller}.mvc/{action}/{id}", new MvcRouteHandler())

{

Defaults = new RouteValueDictionary(new { action = "Index", id = "" }),

});//设置URL Routing格式

routes.Add(new Route("Default.aspx", new MvcRouteHandler())

{

Defaults = new RouteValueDictionary(new { controller = "Customer", action = "Index", id = "" }),

});//设置默认URL指向Customer Controller的Index方法

}

protected void Application_Start(object sender, EventArgs e)

{

RegisterRoutes(RouteTable.Routes);

}

}

【代码1】:Global.asax.cs

下面来实现Customer 的Model、Controller及View:

Model: 在项目中的Model文件夹下,新建一个"Linq to SQL Classes",将Northwind数据库中的Customer表拖拽到其设计视图中。这样就完成了Customer对应的Model。如图4

Controller: 在项目中的Controller文件夹下,新建一个"MVC Controller Class",命名为CustomerContoller.cs。 在此类中添加一个公有方法Index,此方法及为在Global.asax.cs中设置好的默认URL所映射的方法。

public class CustomerController : Controller

{

public void Index(string id)

{

Northwind.Models.NorthwindDataContext dc = new Northwind.Models.NorthwindDataContext();

IList<Northwind.Models.Customer> customers = dc.Customers.Take(10).ToList();//取数据库中的10个Customer记录

RenderView("Index", customers);//返回Index View

}

}

【代码2】:CustomerController.cs

View: 上面Index方法的代码表示CustomerContoller的Index方法执行后,需要返回一个名称为Index的View,以便将数据呈现给用户。下面来添加这个Index View:在项目的View文件中,新建一个子文件夹Customer。与Customer Controller有关的View将保存在此文件夹下。新建一个"MVC View Class"并命名为Index.aspx。在前面的RenderView("Index", customers)方法中,customers参数是Controller传递给View所需的数据,该参数的类型为IList<Northwind.Models.Customer>。为了在View中方便使用此强类型的数据,View.aspx.cs使用了如下代码:注意粗体部分

public partial class Index : ViewPage<IList<Northwind.Models.Customer>>

{

}

【代码3】:Index.aspx.cs

View.aspx代码如下:ViewData这一成员变量的类型及为上面提到的IList<Northwind.Models.Customer>类型。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Edit.aspx.cs" Inherits="Northwind.Views.Customer.Edit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title></title>

</head>

<body>

<div>

<table>

<tr>

<td>Edit</td>

<td>Customer ID </td>

<td>Company Name </td>

<td>Contact Name </td>

<td>Contact Title </td>

</tr>

<% foreach (Northwind.Models.Customer customer in ViewData)

{%>

<tr>

<td><a href="Customer.mvc/Edit/<%= customer.CustomerID %>">Edit</a></td><!—URL指向Customer Contoller的Edit方法 -->

<td></td>

<td>  <%= customer.CustomerID %></td>

<td> <%= customer.CompanyName  %></td>

<td> <%= customer.ContactName  %></td>

<td><%= customer.ContactTitle  %></td>

</tr>

<%} %>

</table>

</div>

</body>

</html>

【代码4】:Index.aspx

下面来实现Customer Controller的Edit方法。在CustomerController.cs中添加如下代码:

public void Edit(string id)

{

Northwind.Models.NorthwindDataContext dc = new Northwind.Models.NorthwindDataContext();

Customer c = dc.Customers.Single(cus => cus.CustomerID == id);//从数据库中取出参数id所对应的的一个Customer记录

RenderView("Edit", c);//返回Edit View

【代码5】:CustomerController.cs中的Edit方法

相应的在项目中的View/Customer/文件夹下,添加Edit View Edit.aspx:

public partial class Edit : ViewPage<Northwind.Models.Customer>

{

}

【代码6】:Edit.aspx.cs

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Edit.aspx.cs" Inherits="Northwind.Views.Customer.Edit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title></title>

</head>

<body>

<!—下面的 html form 将用户的输入提交到Customer Contoller的Update方法 -->

<%using( Html.Form<Northwind.Controllers.CustomerController>(cc=>cc.Update(ViewData.CustomerID))){ %>

<div>

Customer ID: <%= ViewData.CustomerID  %> <br />

Company Nmae: <%= Html.TextBox("Customer.CompanyName", ViewData.CompanyName) %> <br />

Contact Name: <%= Html.TextBox("Customer.ContactName",ViewData.ContactName) %><br />

Contact Title: <%= Html.TextBox("Customer.ContactTitle",ViewData.ContactTitle) %>

</div>

<%= Html.SubmitButton("Save") %>

<%} %>

</body>

</html>

【代码7】:Edit.aspx

代码7中使用了MVC框架中的一个帮助类Html。此类可以生产View中常用的界面元素,例如 html form,文本输入框等。

下面来实现CustomerController的Update方法:

public void Update(string id)

{

Northwind.Models.NorthwindDataContext dc = new NorthwindDataContext();

//从数据库中取出参数id所对应的的一个Customer记录:

Customer cust = dc.Customers.Single(c => c.CustomerID == id);

//将Edit View中的用户的更改赋值到cust对象:

BindingHelperExtensions.UpdateFrom(cust, Request.Form);

dc.SubmitChanges();

RedirectToAction("Index");//跳转到Index View

}

【代码8】:CustomerController.cs中的Update方法

上面的代码通过ASP.NET MVC框架实现了Customer的列表、编辑及更新功能,可以看出MVC将应用程序的Model、View及Controller三部分"优雅的"分离,真正实现了高内聚、低耦合的灵活架构,大大降低了程序的复杂性,提高了可扩展性及可重用性。这一框架对Web开发带来的影响不仅是是技术上的变化,更是Web程序设计思想的变化 -- Web程序不再是一些列功能页面的集合,而是又Controller控制的功能单元的集合,Web程序更像是一组通过其URL对外开放的"API"。

.NET Web开发之.NET MVC框架的更多相关文章

  1. Mithril – 构建杰出 Web 应用的 JS MVC 框架

    Mithril 是一个客户端的 Javascript MVC 框架.它是一个工具,使应用程序代码分为数据层,UI 层和粘合层.提供了一个模板引擎与一个虚拟的 DOM diff 实现,用于高性能渲染,支 ...

  2. Vim下的Web开发之html,CSS,javascript插件

    Vim下的Web开发之html,CSS,javascript插件   HTML 下载HTML.zip 解压HTML.zip,然后将里面的所有文件copy到C:\Program Files\Vim\vi ...

  3. Web开发之Tomcat&Servlet

    <!doctype html>01 - JavaEE - Tomcat&Servlet figure:first-child { margin-top: -20px; } #wri ...

  4. 移动web开发之rem适配布局

    移动web开发之rem适配布局 方案: 页面布局文字能否随着屏幕大小变化而变化 流式布局和flex布局主要针对于宽度布局,那高度如何布局? 怎样让屏幕发生变化的时候元素高度和宽度等比例缩放? 1. r ...

  5. 【WEB】初探Spring MVC框架

    Spring MVC框架算是当下比较流行的Java开源框架.但实话实说,做了几年WEB项目,完全没有SpringMVC实战经验,乃至在某些交流场合下被同行严重鄙视“奥特曼”了.“心塞”的同时,只好默默 ...

  6. .NET web开发之WebApi初试水

    前几天看了.NET的EF(Entity Framework),发现居然有这么先进的东西,只要操作几个类就可以完成数据库的增删查改,而且可以用数据库直接导出类(DB First).也可以用类来生成数据库 ...

  7. web开发中的MVC框架与django框架的MTV模式

    1.MVC 有一种程序设计模式叫MVC,核心思想:分层,解耦,分离了 数据处理 和 界面显示 的代码,使得一方代码修改了不会影响到另外一方,提高了程序的可扩展性和可维护性. MVC的全拼为Model- ...

  8. python Web开发之 WSGI & uwsgi & uWSGI

    首先弄清下面几个概念: WSGI 全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server ...

  9. python web开发之flask框架学习(2) 加载模版

    上次学习了flask的helloword项目的创建,这次来学习flask项目的模版加载: 第一步:创建一个flask项目 第二步:在项目目录的templates文件夹下创建一个html文件 第三步: ...

随机推荐

  1. Query获取值常用

    Query获取Select选择的Text和Value:语法解释:1. $("#select_id").change(function(){//code...});   //为Sel ...

  2. javascript 多图无缝切换

    思路只要是ul移动前,首先将当前显示的li克隆岛ul最后,当每次运动执行完毕后,再将前面的li删除,如此循环. <!DOCTYPE html> <html> <head& ...

  3. Comparator TreeSet

    package study; import java.util.Comparator;import java.util.TreeSet; public class TreeSetTest { publ ...

  4. 优化:代码移动code motion

    代码移动code motion-一种常见的优化-这种优化是把(一种需要执行多次但计算结果不会改变)的计算移到前面-这种优化一般需要程序员自行移动代码,不能依靠编译器(编译器担心会有副作用) 看看代码就 ...

  5. uva 10763 Foreign Exchange <"map" ,vector>

    Foreign Exchange Your non-profit organization (iCORE - international Confederation of Revolver Enthu ...

  6. (原)使用mkl计算特征值和特征向量

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5585271.html 参考文档:mkl官方文档 lapack_int LAPACKE_sgeev(in ...

  7. CSS3前缀

    我们经常会遇到写的有些css3属性会在不同的浏览器下呈现不兼容的情况,那是因为浏览器内核不同而导致的兼容性问题. 首先我们需要先了解一下目前的几种现代浏览器的内核,主流内容主要有Mozilla(熟悉的 ...

  8. php-app开发接口加密

    自己平时工作中用到的一套接口加密规则,记录下来以后用: /** 2 inc 3 解析接口 客户端接口传输规则: 1.用cmd参数(base64)来动态调用不同的接口,接口地址统一为 http://a. ...

  9. dataGridView行高自适应

    今天从网上查询相关datagridview行高自适应的信息时,好多都是告诉你直接用下面三行代码: dataGridView1.AutoSizeRowsMode = DataGridViewAutoSi ...

  10. mysql 针对单张表的备份与还原

    A.MySQL 备份工具xtrabackup 的安装 . percona 官方xtrabackup 的二进制版本:二进制版本解压就能用了. . 解压xtrabackup & 创建连接 -Lin ...