ASP.NET MVC 5 Web编程2 -- URL映射(路由原理)
本章将讲述ASP.NET MVC5 的路由原理,即URL映射机制。
简单点就是解释:为什么MVC在浏览器输入地址就能访问到类(或类中的方法)?这是怎么做到的?我自己可以通过.NET写出一个自己的MVC框架吗?
答案是:可以。
模拟URL映射
先来看一个Demo,在传统的.NET WebForms项目中,实现URL的拦截。
打开VS2013,新建一个“ASP.NET Web窗体应用程序”项目,并取名为Demo4URLRouting。
为了方便测试,注释掉Default.aspx页面的内容和模板引用。这样做以后,看起来是这样
然后新建一个ControllerFactory类,实现IHttpHandler接口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace Demo4URLRouting
{
/// <summary>
/// 自己写的ControllerFactory,试图扮演MVC5中的RouteConfig(路由配置)角色。
/// </summary>
public class ControllerFactory : IHttpHandler
{
ControllerFactory()
{
} public bool IsReusable
{
get;
set;
} public void ProcessRequest(HttpContext context)
{
context.Response.Write(string.Format("ControllerFactory来拦截请求-> URL为: {0}",context.Request.RawUrl));
}
}
}
下一步,打开Web.config配置文件,在system.webServer节点下添加一项handlers配置
代码如下:
<!--for url routing test Start-->
<handlers>
<add name="ControllerFactory" verb="*" path="*Account/*" type="Demo4URLRouting.ControllerFactory,Demo4URLRouting" preCondition="integratedMode"/>
</handlers>
<!--for url routing test End-->
此配置的意图是:拦截站点URL中包含Account关键字的全部URL地址。
按F5运行项目,在地址栏站点后,输入account,发现已成功被ControllerFactory类拦截。
继续,输入/account/login。发现地址未被拦截。而是跳转到了默认项目的登陆页面。
怎么回事呢?
原来,是项目下的Global.asax文件中的内容引起,注释掉RouteConfig注册的路由。
重新输入/account/login,发现已成功被ControllerFactory类拦截。
现在我们修改下ControllFactory类中ProcessRequest方法的代码,实现URL和类及类中方法的映射。(注意,代码做了非常简单的处理,我们假定忽略大小写因素,路由格式也和传统MVC类似)
public void ProcessRequest(HttpContext context)
{
context.Response.Write(string.Format("ControllerFactory来拦截请求-> URL为: {0}",context.Request.RawUrl));
context.Response.Write("<br/>"); /**
* 将拦截的URL地址分发给对应的Controller
**/
//简单处理,截取URL中第一个/和/之间的字符串做为要查找的Controller对象
string url = context.Request.RawUrl;
string actionURL = url.IndexOf('?') > ? url.Substring(, url.IndexOf('?')) : url.Substring();
string[] strArray = actionURL.Split('/');
//得到类名称
string targetClassName = (strArray[] + "Controller");
string methodName = string.Empty;
if (strArray.Length > && !string.IsNullOrEmpty(strArray[]))
methodName = strArray[];//以'/'做分割,类名称后为方法名称
/**
* 从URL获取类名称之后,利用反射实现方法的调用。
**/
//获取Controller实例
object instance = Activator.CreateInstance(Type.GetType(string.Format("Demo4URLRouting.Controllers.{0}", targetClassName)));
if (instance != null)
{
object outputObj = null;//方法输出内容
if (string.IsNullOrEmpty(methodName) || instance.GetType().GetMethod(methodName) == null)
methodName = "Index";//如果url没有输入方法或方法不存在,默认调用Index方法
try
{
//调用实例方法
outputObj = instance.GetType().GetMethod(methodName).Invoke(instance, null);
context.Response.Write(outputObj);
}
catch(MissingMethodException mme)
{
context.Response.Write(string.Format("<font color='red'>Error! Method not Found!</font> {0}",mme.Message));
}
}
}
在代码中,进行了简单的url分析,获取类名和方法名,再通过反射机制,实现调用。
然后,为了配合测试,我们在解决方案中新建一个Controllers文件夹,在该文件夹下新建一个类AccountController,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace Demo4URLRouting.Controllers
{
public class AccountController
{
public string Index()
{
return "this is the AccountController,<b>Index</b> method.";
} public string HelloWorld()
{
return "this is <font color='red'>HelloWorld method</font> which is in the Class named AccountController.";
} }
}
AccountController类中定义了两个方法,Index()和HelloWorld()。然后我们通过浏览器进行访问
可以看到,通过在浏览器地址中,输入/Account,实现对AccountController类中Index方法的访问;输入/Account/HelloWorld实现对AccountController类中的HelloWorld方法的访问。
到此,我们初步实现了在WebForms环境下,URL到类的映射。此过程的核心是handlers的配置和利用反射原理调用类中的方法。Demo的不足是没有去消除大小写问题,没有更灵活的路由配置等。
那么问题来了,MVC中这一整套URL映射的机制,是如何实现的呢?
MVC5 URL映射机制
实际上,在写本篇文章之前,我翻看了大量网上有关MVC的资料,发现大多数对MVC映射机制(也叫MVC路由机制)的描述都非常笼统。
类似不懂装懂,或者让你去理解Model-View-Controller的三层,什么业务分离,或者说了半天说一堆废话。。。我是深恶痛绝的。如果仅仅是解释微软MSDN上能查到的东西?那你的解释意义在哪里?不说了,泡沫信息太多了。
在了解MVC URL映射机制这一套原理之前,你首先要了解ASP.NET Routing。 ASP.NET Routing是.NET的一套独立组件。总的来说,它可以做两件事情:
1. 将URL请求地址的片段转交到handler处理;
2. 构造(创建)URL地址。
Routing目前的信息实在太少,感兴趣的可以在MSDN上做初步了解。总的来说,Routing做了我们前面模拟做的所有事情,而且毋庸置疑,做的更好更强大。
在MVC中,从URL到Controller,简要过程大概是这样:
URL --> RouteData对象 --> MvcHandler对象 --> IControllerFactory接口 --> Controller
这个过程很复杂,要详细阐述其过程,估计要三篇文章以上的篇幅。这里就不再阐述。
MVC框架中,RouteConfig类中这段代码已经做了URL到Controller映射的所有工作。你所需要做的,只是匹配Controller了。
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
总结
本篇文章重点讲述了ASP.NET MVC中的URL映射机制。先是通过在WebForms中模拟URL映射,让初学者有一个直观的认识。然后简要的介绍了MVC中URL映射的机制。由于篇幅所限,在介绍URL映射机制时,只做了简要的阐述。因为知识量很大,而且建议读者要有ASP.NET Routing组件的基础。关于Routing组件,以后有空的话,我再单独写文章来讲。
在下一篇文章中,我将讲述Controller的实际应用及扩展,项目中Controller扮演的角色。敬请期待。
ASP.NET MVC 5 Web编程2 -- URL映射(路由原理)的更多相关文章
- MVC 5 Web编程2 -- URL映射
ASP.NET MVC 5 Web编程2 -- URL映射(路由原理) 2015-02-12 08:50 by hangwei, 704 阅读, 5 评论, 收藏, 编辑 本章将讲述ASP.NET M ...
- ASP.NET MVC 5 Web编程1 -- 入门
开篇引言 说起ASP.NET MVC,我想作为WebForms开发者第一点要问的是:为什么要使用它?我的理解是:MVC是更细节化的框架,“细节可控”意味着你的系统更精致.具体体现在应用上.MVC的出现 ...
- ASP.NET MVC 5 Web编程4 -- Razor视图引擎
Razor简介 Razor是ASP.NET新增的一个视图引擎,由微软全球最年轻的副总裁,有着"ASP.NET之父"称呼的Scott Guthrie主导的团队开发. 主导Razor开 ...
- ASP.NET MVC 4 Web编程
http://spu.jd.com/11309606.html 第1章 入门第2章 控制器第3章 视图第4章 模型第5章 表单和HTML辅助方法第6章 数据注解和验证第7章 成员资格.授权和安全性第8 ...
- ASP.NET MVC 5 Web编程5 -- 页面传值的方式
本篇文章将讲述MVC的页面传值方式,具体包括:后端向前端传值(Controller向View传值):前端向后端传值(View向Controller传值):Action与Action之间的传值. 回顾 ...
- ASP.NET MVC 5 Web编程3 -- Controller的应用及扩展
Controller基础 一. 访问修饰符 1.1 类的访问修饰符 Controller类的访问修饰符必须是public,url才能被拦截. internal能编译通过,但无法拦截url请求.priv ...
- ASP.NET MVC 4高级编程(第4版)
<ASP.NET MVC 4高级编程(第4版)> 基本信息 作者: (美)Jon Galloway Phil Haack Brad Wilson K. Scott All ...
- ABP示例程序-使用AngularJs,ASP.NET MVC,Web API和EntityFramework创建N层的单页面Web应用
本片文章翻译自ABP在CodeProject上的一个简单示例程序,网站上的程序是用ABP之前的版本创建的,模板创建界面及工程文档有所改变,本文基于最新的模板创建.通过这个简单的示例可以对ABP有个更深 ...
- ASP.NET MVC和Web API中的Angular2 - 第2部分
下载源码 内容 第1部分:Visual Studio 2017中的Angular2设置,基本CRUD应用程序,第三方模态弹出控件 第2部分:使用Angular2管道进行过滤/搜索,全局错误处理,调试客 ...
随机推荐
- Linux deepin 下sublimes配置g++ openGL
参考 :http://blog.csdn.net/u010129448/article/details/47754623 ubuntu 下gnome只要将代码中deepin-terminal改为gno ...
- 电脑运行msi安装包提示the error code is 2503/2502如何解决
当在电脑中运行msi安装包时,出现the error code is 2503或者2502错误提示,其实是由于没有运行的权限导致的,但是又不能右击以管理员身份运行,那么应该如何操作呢?对于这样的问题, ...
- byte[] 转十进制
short s = 0; //一个16位整形变量,初值为 0000 0000 0000 0000 byte b1 = 1; //一个byte的变量,作为转换后的高8位,假设初值为 0000 0001 ...
- Leetcode: Palindrome Partitioning II
参考:http://www.cppblog.com/wicbnu/archive/2013/03/18/198565.html 我太喜欢用dfs和回溯法了,但是这些暴力的方法加上剪枝之后复杂度依然是很 ...
- Android Studio 引用 gson-2.6.2-sources
1.拷贝到libs下
- display:inline-block的间隙问题和解决办法
1.display:inline-block在水平方向的间隙: 代码如下: <style type="text/css"> *{margin:0; padding:0; ...
- GIT版本管理工具
原文:http://blog.csdn.net/ithomer/article/details/7527877 Git 是一个分布式版本控制工具,它的作者 Linus Torvalds 是这样给我们介 ...
- 编写高质量的 Java 代码
代码质量概述 代码质量所涉及的5个方面,编码标准.代码重复.代码覆盖率.依赖项分析.复杂度分析.这5方面很大程序上决定了一份代码的质量高低. 我们分别来看一下这5方面:编码标准:这个想必都很清楚,每个 ...
- Good Bye 2016 - A
题目链接:http://codeforces.com/contest/750/problem/A 题意:有n场比赛要打,第i场比赛需要花i*5分钟来完成,比赛从20:00开始.然后新年派对24:00开 ...
- oracle(sql)基础篇系列(三)——数据维护语句、数据定义语句、伪列
DML语句 insert 向表中插入新的记录 --三种插入方式 --(1)不写字段的名字,直接按照字段的顺序把值逐个往里插 insert into dept2 values(50,'DANAM ...