ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第三篇
摘要
本文对ASP.NET MVC的全局运行机理进行一个简要的介绍,以使得朋友们更好的理解后续文章。
前言
在上一篇文章中,我们实现了第一个ASP.NET MVC页面。对于没有接触过这个框架的朋友来说,可能对有些地方会迷惑,所以这篇文章我将通过图示配合文字的方法,站在全局的角度介绍一些ASP.NET MVC的运行机制,这样可以帮助朋友们更好的理解后续文章。^_^
全局
首先我们来看一副图片,由于这幅图是我自己画的,不是摘自微软官方,所以如果有什么不到位的地方还望海涵!
首先,用户通过Web浏览器向服务器发送一条url请求,这里请求的url不再是xxx.aspx格式,而是http://HostName/ControllerName/ActionName/Parameters的样子。这个请求被ASP.NET MVC的路由映射系统截获。(路由映射可以在Global.asax中配置,我们一会再说)路由映射系统按照映射规则,解析出控制器名ControllerName,Action名ActionName和各个参数Parameters,然后,找寻Controllers目录下的ControllerNameController.cs这个控制器类,默认情况下,系统总是找寻Controllers目录下的“控制器名+Controller”这么一个类,然后,找寻这个类下与ActionName同名的方法,找到后,将Parameters作为参数传给这个方法,而后Action方法开始执行,完成后返回相应视图,默认情况下,会返回Views目录下与ControllerName同名的目录下的与ActionName同名的aspx文件,并且将ViewData传递到视图。ViewData中一般包含了控制视图显示的控制量以及视图显示需要的数据。
我们按以上思路回顾一下上一篇中主页的请求过程。我们传递的url是http://localhost/Home/Index。默认路由规则下,将ControllerName设为“Home”,ActionName设为“Index”,没有参数。于是系统找寻Controllers目录下的HomeController类的Index方法,成功找到,于是执行之。这个方法调用Mock的Model取出一些数据,放入ViewData相应键值项里。然后返回视图,返回的是Views下Home下的Index.aspx。这个视图取出ViewData中的数据按照一定格式呈现,于是完成了一次典型的ASP.NET MVC调用。
路由
从上面可以看出,ASP.NET MVC中路由是很重要的。它直接决定了如何解析url,因此决定了系统如何工作。那么,下面我们来揭开路由神秘的面纱。
打开我们Demo下的Global.asax.cs文件,可以看到如下代码:
Global.asax.cs:
2using System.Collections.Generic;
3using System.Linq;
4using System.Web;
5using System.Web.Mvc;
6using System.Web.Routing;
7
8namespace MVCDemo
9{
10 // Note: For instructions on enabling IIS6 or IIS7 classic mode,
11 // visit http://go.microsoft.com/?LinkId=9394801
12
13 public class MvcApplication : System.Web.HttpApplication
14 {
15 public static void RegisterRoutes(RouteCollection routes)
16 {
17 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
18
19 routes.MapRoute(
20 "Default", // Route name
21 "{controller}/{action}/{id}", // URL with parameters
22 new { controller = "Home", action = "Index", id = "" } // Parameter defaults
23 );
24
25 }
26
27 protected void Application_Start()
28 {
29 RegisterRoutes(RouteTable.Routes);
30 }
31 }
32}
我们拣重点说。注意上面有个routes.MapRoute方法。这个方法的作用是向系统增加一条路由规则。这里唯一的一条规则是系统默认增加的,第一个参数是规则名,是一个普通字符串。关键是第二个参数,它也是一个字符串,但是它描述了如何解析url。可以这样理解,它描述了url串HostName后面部分如何匹配,其中带{}的表示参数匹配,如果不带则表示字符串匹配。
例如,上面的{controller}/{action}/{id}表示如果HostName后面有三段由“/”分割的字符串,则这个url被匹配,并且分别被解析成控制器名,Action名和一个叫“id”的参数。如果你输入的是http://localhost/Home/Index/1则后面的“1”将被当做参数id的值,但是如果你请求http://localhost/Home/Index/1/2,抱歉,你的请求无法成功,因为这条路由规则没法匹配你的url,因为你的HostName后面有四段,而这个路由规则只能匹配三段的。
也许你还注意到一个问题,http://localhost/Home/Index明明HostName后面只有两段,怎么也被匹配了呢?这就是MapRoute方法的第三个参数起作用了。这个参数的作用是为上面规则中各个{}匹配段设置默认值,如上,id的默认值为"",即空。所以在http://localhost/Home/Index中,虽然没有显示指定id,但是它依然可以匹配成功,默认作为空值。如果你把其中id=""去掉,你会发现http://localhost/Home/Index已经无法匹配了。依次类推,http://localhost/Home/也可以匹配成功,因为{action}默认是Index,http://localhost/也可以匹配成功,因为默认{controller}为Home,所以,在这条默认值下http://localhost/Home/Index和http://localhost/是等效的。
综上分析,我们得出一条重要结论:在默认值被设置的情况下,映射规则“配少不配多”,少的部分由默认值代替。
上面的匹配规则中,三个匹配段都带大括号的,都是参数匹配,下面我们来说说强字符串匹配。例如,我们有一个url需要这样http://localhost/Category/Detail/Name。如果按照上面的匹配规则,Name段的值会被匹配到id中去,可是我们想在CategoryController的Detail方法中使用名叫“name”的参数而不是使用名叫“id”的参数,怎么办呢?很简单,我们增加一下一条匹配规则:
2using System.Collections.Generic;
3using System.Linq;
4using System.Web;
5using System.Web.Mvc;
6using System.Web.Routing;
7
8namespace MVCDemo
9{
10 // Note: For instructions on enabling IIS6 or IIS7 classic mode,
11 // visit http://go.microsoft.com/?LinkId=9394801
12
13 public class MvcApplication : System.Web.HttpApplication
14 {
15 public static void RegisterRoutes(RouteCollection routes)
16 {
17 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
18
19 routes.MapRoute(
20 "Category", // Route name
21 "Category/Detail/{name}", // URL with parameters
22 new { controller = "Category", action = "Detail", name = "" } // Parameter defaults
23 );
24
25
26 routes.MapRoute(
27 "Default", // Route name
28 "{controller}/{action}/{id}", // URL with parameters
29 new { controller = "Home", action = "Index", id = "" } // Parameter defaults
30 );
31
32 }
33
34 protected void Application_Start()
35 {
36 RegisterRoutes(RouteTable.Routes);
37 }
38 }
39}
可以看到,我们在默认规则前增加了一条规则,其中其中控制器名和Action名不再是参数,而变成了强字符串(没有{})。这时,当我们请求的url是http://localhost/Cateogry/Detail/para的形式时,就会直接匹配新加的规则,而para的值不会被赋给成id而是赋给名叫name的变量。
需要注意的是,我们新的路由规则一定要放在前面,因为ASP.NET MVC会自上向下匹配第一条找到的可匹配路由规则。
视图
说完了路由规则,我们再来说说视图。
上面说道,Action方法返回类型是ActionResult,其实这个返回类型不局限于View方法返回ViewResult,它还有很多实现,这里列举几个。
ViewResult:一般呈现某个aspx文件,由View方法返回。
RedirectToResult:使浏览器重定向,由Redirect方法返回。
RedirectToRouteResult:直接交给下一个Action,由RedirectToAction方法返回。
还有几个,先不说了,因为后续文章基本用不到其他的,关于那几个以后朋友们可以自己看相关资料。
小结
看完这篇文章,就基本把90%的障碍扫清了。下面的文章中,将继续我们的实例。在下一篇中,我们来完成发布公告的功能,看看ASP.NET MVC下如何处理表单信息的传递。
ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第三篇相关推荐
- T2噬菌体MVC案例教程
T2噬菌体MVC案例教程 http://www.cnblogs.com/leoo2sk/archive/2008/10/27/1320285.html MVC初学者浅显易懂的教程 转载于:https: ...
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第二篇:第一个页面
摘要 本文首先一步一步完成Demo的第一个页面--首页.然后根据实现过程,说明一下其中用到的与ASP.NET MVC相关的概念与原理. 让第一个页面跑起来 现在,我们来实现公告 ...
- JavaScript组件之JQuery(A~Z)教程(基于Asp.net运行环境)[示例代码下载](一)
(一).概述 现在有好多比较优秀的客户端脚本语言组件, 如: Prototype.YUI.jQuery.mootools.Bindows, Scriptaculous, FCKEditor 等, 都非 ...
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
摘要 本文将简要介绍这个文章系列的目的.形式及大体内容.并且完成开始学习这个系列前所必要的准备工作. 前言 ASP.NET MVC作为微软官方的MVC解决方案,推出有一段时间了 ...
- 第六篇:拦截器( MVC案例教程(基于ASP.NET MVC beta))
http://ljl-xyf.javaeye.com/blog/725196 摘要 本文将对"MVC公告发布系统"的发布公告功能添加日志功能和异常处理功能,借此来讨论A ...
- ASP.NET MVC案例教程——拦截器 Filter
摘要 本文将对"MVC公告发布系统"的发布公告功能添加日志功能和异常处理功能,借此来讨论ASP.NET MVC中拦截器的使用方法. 一个小难题 我们继续完善 ...
- ASP.NET程序设计案例教程《上机操作题》
目录 需求 详细步骤: 完成创建效果图 查看布局效果 布局代码 修改后的效果 运行测试 效果展示 源代码下载地址 需求 创建一个ASP.NET空网站,在其中新建一个网页,显示单击"提交&qu ...
- 案例驱动式Python学习笔记【第三篇】居民身份证信息提取
驱动案例 居民身份证是每位居民的唯一身份标识,18位的居民身份证号的信息包含省.市.出生日期和性别等信息, 那么本节将介绍如何按需提取相应的信息.居民身份证是每位居民的唯一身份标识,18位的居民身份证 ...
- asp毕业设计——基于asp+sqlserver的网上选课系统设计与实现(毕业论文+程序源码)——网上选课系统
基于asp+sqlserver的网上选课系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+sqlserver的网上选课系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...
最新文章
- 网站HTML删除数据库中数据语句,如何以编程方式删除WebSQL中的数据库?
- python绘制柱形图-Python openpyxl Excel绘制柱形图
- Request请求总结
- Vue2.0 入门 安装Vue-cli
- 解决PHP生成校验码时“图像因其本身有错无法显示”的错误
- 软考解析:2017年上半年下午试卷
- Eclipse开发常用快捷键
- 线程同步与互斥........
- zabbix详解(三)——zabbix源码安装与部署
- Oracle数据库sys和system用户的默认密码及如何修改密码
- ASCSDK-------通用包接入文档(COCOS篇)
- springboot项目启动类报错
- Linux应用层24点小游戏,C++ Builder构建算二十四点小游戏
- 麦吉尔大学计算机工程的世界排名,「麦吉尔大学」2021qs世界排名_申请条件 - 言顶留学...
- python 处理英文步骤
- NSDate中夏令时的坑你知道吗
- AIGC基础:从VAE到DDPM原理、代码详解
- 一台电脑登陆两个微信账号
- Win11系统注销在哪?Win11系统注销的方法
- 基于BES+DSP 的音频系统方案设计
热门文章
- HIVE: hive.error.on.empty.partition
- linux文件三种时间及stat的用法
- TypeScript入门教程 之 const
- Spring JDBC和JdbcTemplate CRUD与DataSource示例
- TAIGA项目管理平台快速安装
- jQuery 源码解析(三十一) 动画模块 便捷动画详解
- windows常用指令
- 【Python】Tkinter图形界面设计(GUI)
- 【Python】 运算符
- angular 错误处理_可能出什么问题了? 如何处理Angular中的错误