白话学习MVC,路由原理

首先大家明白一下形似的章程

    大家只须要在web.config配置文件中做映射处理即可。

 1、概要

当大家新建贰个MVC项目时,打开她的Web.Config文件能够窥见

    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 我们知道ScriptModule 类就是管理用于 ASP.NET 中 AJAX 功能的 HTTP 模块,在此我们不做介绍
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> //这个UrlRoutingModule类才是重点
    </httpModules>

这几个HttpModule,拦截全数请求,对请求进行处理,最后创建和实践合适的拍卖请求的HttpHandler(MVC三之后,这一个UrlRoutingModule集成到MVC程序集中了)。

 

  当客户端在地头浏览器上输入网站来呼吁大家的三个MVC程序时,服务端接收到请求…..此处省略N个字(和asp.net处理①样)…..

  HttpApplication的风波注册,即将 UrlRoutingModule
注册到HttpApplication的风云中

public class UrlRoutingModule : IHttpModule
{
    protected virtual void Init(HttpApplication application)
    {   //开始只是把要执行的具体方法注册到事件中,等待事件被触发时,在执行已被注册的方法。
        application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache); 
        application.PostMapRequestHandler += new EventHandler(this.OnApplicationPostMapRequestHandler);
    }
}

  注册完事件之后,那么快要开端履行HttpApplication事件。

1、执行Global.asax文件中Application_Start方法。
即:在此处将三个要好定义的路由规则注册到路由集合中。那么些路由集合能够由RouteTable.Routes获得。

 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
        }

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Default", // 路由名称
                "{controller}/{action}/{id}", // 带有参数的 URL
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
            ); //在路由表里添加一条路由规则
        }

本章将讲述ASP.NET MVC5 的路由原理,即UBMWX五L映射机制。

ASP.NET路由[ASP.NET Routing]

  ASP.NET路由允许你在动用U汉兰达L时不必相称到网址中具体的公文,因为这些UPRADOL不必相称到一个文书,你利用了描述用户作为且更便于被用户知道的UEscortL。

  ASP.NET MVC框架和ASP.NET动态数据(Dynamic
Data)扩充路由为MVC应用和动态数据应用扩张了特点。

  在不利用路由的ASP.NET应用中,三个新的乞请会被映射到一个大体文件并由该文件处理这一个请求,例如八个.aspx文件。例如,如下请求会题映射到3个富含代码和标签来向浏览器渲染响应的Products.aspx文件。Web页面职员动用id=四的查询字符来分明呈现的始末。

  使用ASP.NET路由,你能够定义映射请求-处理程序(request-handler)文件的U奥德赛L情势,但没须求在将那些文件的名字包罗在这几个U瑞虎L中。除此而外,你还足以由此在UOdysseyL形式中选用占位符来向请求处理程序传输变量数据,而不要采用查询字符串。

  例如,如下请求 ,路由分析器会向页面处理器传入Products,show,beverages那些值。在那些例子中,倘使应用server/application/{area}/{action}/{category}U途睿欧L形式定义路由,页面处理器将会收取三个字典集合,这一个集合中带有以下键值对,area:Products,action:show,category:beverages。假诺是在二个不被UBMWX5L路由管理的伸手中,/Products/show/beverages片断将会被看作应用中的2个文书路径解释实施。

白话学习MVC,路由原理。首先种样式:

 <system.web>
    <urlMappings enabled="true">

      <add url="~/d" mappedUrl="SmackBio.WebSocketSDK.GenericHandler"/>

    </urlMappings>

证明:那里的url正是大家需求在伸手的有血有肉写法,然后mappedUrl则是大家实在项目中的处理地方。

其次种情势:

 <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>    
      <add path="/socket" verb="*" name="GenericHandler" type="SmackBio.WebSocketSDK.GenericHandler"/>
    </handlers>
  </system.webServer>

诠释:这里的path正是咱们呼吁的输入地址,type则是大家的实际上项目中的方法类职位。

2、依次执行HttpApplication的事件。  

BeginRequest
AuthenticateRequest
PostAuthenticateRequest
AuthorizeRequest
PostAuthorizeRequest
ResolveRequestCache
PostResolveRequestCache 在UrlRoutingModule类中,在此事件中注册了一个执行方法,即:OnApplicationPostResolveRequestCache
PostMapRequestHandler                                                       OnApplicationPostMapRequestHandler
AcquireRequestState
PostAcquireRequestState
PreRequesHandlerExecute
PostRequeshandlerExecute
ReleaseRequesState
PostReleaseRequestState
UpdateRequestCache
PostUpdateRequestCach
LogRequest
PostLogRequest
EndRequest

OnApplicationPostResolveRequestCache方法

private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{
    HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
    this.PostResolveRequestCache(context);
}
//这里用HttpContextWrapper类包装当前的HttpContext,实质上也是一个请求的上下文。他可以使用诸如Typemock Isolator或Rhino Mocks的Mock对象框进行模拟变得更简单。
//并把这个包装之后的上下文作为PostResolveRequestCache的参数

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

public virtual void PostResolveRequestCache(HttpContextBase context)
{
    RouteData routeData = this.RouteCollection.GetRouteData(context);
//GetRouteData方法内部遍历路由集合中的每个路由对象去和上下文中指定的请求URL去匹配。如成功,就返回当前的路由对象RouteData,如不成功,返回null
//this.RouteCollection就是RouteTable.Routes,即:路由集合。

    if (routeData != null)----这里便是判断是否匹配成功
    {
        IRouteHandler routeHandler = routeData.RouteHandler;----//获取一个处理当前匹配成功的路由的对象
     //这个routeHandler其实就是一个MvcRouteHandle类
     ----因为在第一句中执行的GetRouteData方法中,为RouteData的RouteHandler属性赋值为MvcRouteHandler
        if (routeHandler == null)
        {
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
        }
        if (!(routeHandler is StopRoutingHandler))
        {
            RequestContext requestContext = new RequestContext(context, routeData);//把当前的请求的信息和与当前请求匹配成功的路由信息再包装起来。
            IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
            //根据包装后的请求信息,最终得到一个MvcHandler
       ---MvcRouteHandler中只有一个方法,GetHttpHandler方法,返回MvcHandler,Mvc中处理请求的类。
       ---PageRouteHandler中也只有一个方法,GetHttpHandler方法,返回的是Page,asp.net中处理请求的类。 

亚洲必赢官网 1亚洲必赢官网 2MvcRouteHandler

    public class MvcRouteHandler : IRouteHandler
    {

        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new MvcHandler(requestContext);
        }

        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
        {
            return this.GetHttpHandler(requestContext);
        }
    }

 

          if (httpHandler == null)

            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler.GetType() }));
            }
            //RequestData类是UrlRoutingModule类中嵌套的一个私有类,把处理请求的类和当前请求的虚拟路径
            RequestData data2 = new RequestData {
                OriginalPath = context.Request.Path,
                HttpHandler = httpHandler
            };
            context.Items[_requestDataKey] = data2;
            //把封装的处理类MvcHandler和请求的虚拟路径,赋值到 HttpContextWrapper类中。(这样在用到处理类时,就需要实例化,直接取值即可)
            //HttpContextWrapper类包装当前的HttpContext,实质上也是一个请求的上下文。
            context.RewritePath("~/UrlRouting.axd");

context.RemapHandler(httpHandler);//博客是里这里是这么一句,但是我反编译没找到,可能是版本的问题吧!
//将MvcHandler 实例 映射到管线中(通常我们是利用web.config 进行配置的,但是MvcHandler 没有默认无参构造函数,所以直接通过向其传递一个实例进行映射)

} } } 

OnApplicationPostMapRequestHandler方法
该方法做的事情很简单,就是重写下请求路径,让输出的路径和输入的路径相同,在这里用来记忆输入路径的是context.Items[],从上下两段代码中可以看到.
这个事件负责根据文件扩展名映射到具体的httphandle处理类,而MVC的URL信息没有具体的文件后缀名 为了使处理模块能够在iis7中实现路由,则采取了这么一种简单的解决办法。先把路径指向~/UrlRouting.axd,在此事件中会设置一个UrlRouting.axd类型的Handler避免报错,并在下一步事件中替换掉此处的Handler再把~/UrlRouting.axd这个路径给改回来。

亚洲必赢官网 3亚洲必赢官网 4View Code

private void OnApplicationPostMapRequestHandler(object sender, EventArgs e)
{
    HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
    this.PostMapRequestHandler(context);
}



 public virtual void PostMapRequestHandler(HttpContextBase context)
{
    RequestData data = (RequestData) context.Items[_requestDataKey];
    if (data != null)
    {
        context.RewritePath(data.OriginalPath);
        context.Handler = data.HttpHandler;
    }
}

 

上文中拿走了3个MvcHandler类实例,MvcHandler继承实现了IHttpAsyncHandler,
IHttpHandler,
IRequiresSessionState四个接口。而那两个接口如若都落实了,在MVC框架下是否任何http请求就能够通吃了吧?从MSDN我们获悉,事实不是那般的:小心,就算MvcHandler 实现 IHttpHandler,也不可能将其映射为处理程序(例如.mvc
文件扩充名),因为此类不协理无参数构造函数。 (它唯一的构造函数须要三个RequestContext 对象)
而是,幸亏,大家还有MvcHttpHandler。

如你所知,MvcHttpHandler能够“弥补”MvcHandler的阙如,为何如此说吗?因为MvcHandler未有无参的构造函数,由此固然MvcHandler达成了
IHttpHandler接口,在IIS中也无法将其映射为某类文件扩张名的处理程序,而MvcHttpHandler就提供了不经过路由模块的场地下直接处理映射的处理程序。

  • MvcHttpHandler.使用此处理程序可便宜落到实处直接处理程序映射(不通过路由模块)。借使要将文件增加名(如
    .mvc)直接照射到三个 MVC
    处理程序,此处理程序将十一分管用。在里边,MvcHttpHandler 将推行 ASP.NET
    路由一般执行(通过
    MvcRouteHandler

    MvcHandler)的天职。不过,它是用作处理程序而不是用作模块来推行这么些任务的。对负有请求启用
    UrlRoutingModule
    时,平时不采纳此处理程序。

  • MvcHandler.此处理程序负责运行MVC 应用程序的 ASP.NET 管道。它从
    MVC 控制器工厂接收
    Controller
    实例;此控制器处理请求的尤其处理。请注意,即使
    MvcHandler
    实现了
    IHttpHandler,它也不可能映照为处理程序(例如,针对
    .mvc
    文件扩大名),因为此类不帮助无参数构造函数(而处理程序须求是无参数构造函数)。(其唯1的构造函数必要
    RequestContext
    对象。)

简简单单点就是表明:为何MVC在浏览器输入地方就能访问到类(或类中的方法)?那是怎么形成的?笔者本身能够通过.NET写出二个融洽的MVC框架吗?

一、      路由[Routes]

  路由是被处理程序映射的UTiguanL方式。处理程序能够是1个物理文件,例如Web
Form应用中的.aspx文件。处理也能够是拍卖请求的类,例如MVC应用中的控制器。为了定义3个路由,你须要创设1个Route类的实例来钦点UPAJEROL格局,处理程序和可选的路由名称。

  你供给给RouteTable类的Routes静态属性添加Route对象来为运用添加路由。Routes属性是三个RouteCollection对象,当中存放着应用中全部路由规则。

  你数见不鲜未有须求为MVC应用编写代码添加来添加路由规则。Visual
Studio的MVC项目模板包蕴了预配置的U昂CoraL路由规则。他们定义在MvcApplication类,这一个类在Global.asax文件中。

mvc路由安顿情势

那是我们差异应用的映照情势。但是在mvc路由中我们挂起壹般处理程序却发现不行了,上边大家将要布置路由艺术开始展览映射。

在mvc中大家分为三步:

    一.达成拍卖代码程序(完毕一般处理程序继承类IHttpHandler)

亚洲必赢官网 5亚洲必赢官网 6

 1   public class GenericHandler : IHttpHandler
 2     {
 3         public void ProcessRequest(HttpContext context)
 4         {
 5             if (context.IsWebSocketRequest || context.IsWebSocketRequestUpgrading)
 6             {
 7                 context.AcceptWebSocketRequest(new SBWebSocketHandler());
 8             }
 9             else
10             {
11                 context.Response.ContentType = "text/plain";
12                 context.Response.Write("Service running");
13             }
14         }
15 
16         public bool IsReusable
17         {
18             get
19             {
20                 return false;
21             }
22         }
23     }

View Code

   
二.定义2个类路由规则(实现路由IRouteHandler接口然后针对处理代码程序类)

亚洲必赢官网 7亚洲必赢官网 8

 public class PlainRouteHandler : IRouteHandler
    {

        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new GenericHandler();
        }
    }

 public static void RegisterHandler(RouteCollection routes)
        {

            RouteTable.Routes.Add("socket",
                 new Route("socket", new MvcZodiac.Controllers.PlainRouteHandler()));
        }

View Code

 

    三.报了名到程序中(在Global.asax中的Application_Start方法注册)

 RegisterHandler(RouteTable.Routes);

 那里补充一下,那句话肯定要写在路由注册以前,不然不会起作用。例如:

亚洲必赢官网 9

 

 3、HttpApplication事件继续执行

BeginRequest
AuthenticateRequest
PostAuthenticateRequest
AuthorizeRequest
PostAuthorizeRequest
ResolveRequestCache
PostResolveRequestCache 
PostMapRequestHandler                                                       
AcquireRequestState
PostAcquireRequestState
PreRequesHandlerExecute
PostRequeshandlerExecute
ReleaseRequesState
PostReleaseRequestState
UpdateRequestCache
PostUpdateRequestCach
LogRequest
PostLogRequest
EndRequest

在1壹-11个事件的时候得到第几个事件的时候创设的MVCHandler对象进行他的ProcessRequest方法。

public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
{
    protected virtual void ProcessRequest(HttpContext httpContext)
    {
        //使用HttpContextWrapper对HttpContext进行封装,封装的目的是为了解耦以获得可测试性.然后从RequestContext.RouteData中提取Controller名称.
        HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
        this.ProcessRequest(httpContext2);
    }

    protected internal virtual void ProcessRequest(HttpContextBase httpContext)
    {
        IController controller;
        IControllerFactory controllerFactory;
        this.ProcessRequestInit(httpContext, out controller, out controllerFactory); //获取到Controler实例       ----下节详细介绍
        try
        {
                controller.Execute(this.RequestContext); //当前Controler对象的Action的创建与执行                   ----下节详细介绍   
                执行包括:加载TempData, 创建及执行Action,处理Action返回的ActionResult ,保存TempData数据。
        }
        finally
        {
            controllerFactory.ReleaseController(controller); //释放当前Controler对象
        }
    }
}

流程如下图,MvcHandler实例来拍卖请求,他做为处理的主干,当成功之后,释放当前的Controler实例,继续执行HttpApplication事件

亚洲必赢官网 10

 此图摘自:

答案是:可以。

二、      URL模式[URL Patterns]

  1个U路虎极光L格局能够包涵字面值(literal)和可变的占位符(参考U汉兰达L参数)。那些字面值和占位符在UPRADOL片断中经过斜线(/)字符来分别和一定。

  当1个请求到达,这一个U本田CR-VL被分析成片断和占位符,这个变量会提须要请求处理器。这几个历程和将数据通过查询字符串(query
strings)中分析和传导至请求处理器很接近。那二种状态下变量信息都会蕴藏在UGL450L中并传播处理程序的键值对的表单中。对于查询字符串而言,全体键(keys)和值(values)都带有在UEscortL中。对于路由艺术,全部键正是在U途乐L格局中定义的占位符名称,唯有值包括中U奥迪Q7L中。

  在三个UQX56L形式中,你定义的占位符被大括号包裹起来({and})。你能够在七个片断中定义三个占位符,不过它们必须被字面值分隔离。例如,{language}-{country}/{action}正是2个法定的路由形式。不过{language}{country}/{action}不是叁个官方的路由格局,因为它们的占位符之间贫乏字面值或分隔符。因而,路由不可能显明language和country占位符的值是何方分隔。

  下表给出了合法的路由形式,以及其个别能正确相配的URAV4L请求。

路由定义

匹配URL示例

{controller}/{action}/{id}

/Products/show/beverages

{table}/Details.aspx

/Products/Details.aspx

blog/{action}/{entry}

/blog/show/123

{reporttype}/{year}/{month}/{day}

/sales/2008/1/5

{locale}/{action}

/US/show

{language}-{country}/{action}

/en-US/show

模拟URL映射

先来看一个德姆o,在价值观的.NET WebForms项目中,达成U卡宴L的阻挠。

开拓VS20壹三,新建二个“ASP.NET
Web窗体应用程序”项目,并取名字为德姆o四UPAJEROLRouting。

亚洲必赢官网 11

为了便于测试,注释掉Default.aspx页面的内容和模板引用。那样做现在,看起来是那样

亚洲必赢官网 12

下一场新建三个ControllerFactory类,实现IHttpHandler接口。

亚洲必赢官网 13亚洲必赢官网 14

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace Demo4URLRouting
 7 {
 8     /// <summary>
 9     /// 自己写的ControllerFactory,试图扮演MVC5中的RouteConfig(路由配置)角色。
10     /// </summary>
11     public class ControllerFactory : IHttpHandler
12     {
13         ControllerFactory()
14         { 
15         }
16 
17         public bool IsReusable
18         {
19             get;
20             set;
21         }
22 
23         public void ProcessRequest(HttpContext context)
24         {
25             context.Response.Write(string.Format("ControllerFactory来拦截请求-> URL为: {0}",context.Request.RawUrl));
26         }
27     }
28 }

View Code

下一步,打开Web.config配置文件,在system.webServer节点下添加壹项handlers配置

亚洲必赢官网 15

代码如下:

亚洲必赢官网 16亚洲必赢官网 17

<!--for url routing test Start-->
    <handlers>
      <add name="ControllerFactory" verb="*" path="*Account/*" type="Demo4URLRouting.ControllerFactory,Demo4URLRouting" preCondition="integratedMode"/>
    </handlers>
    <!--for url routing test End-->

View Code

此布局的意向是:拦截站点U昂CoraL中涵盖Account关键字的整个ULANDL地址。

按F5周转品种,在地点栏站点后,输入account,发现已成功被ControllerFactory类拦截。

亚洲必赢官网 18

接轨,输入/account/login。发现地址未被截留。而是跳转到了默许项指标登陆页面。

亚洲必赢官网 19

怎么回事呢?

本来,是连串下的Global.asax文件中的内容引起,注释掉RouteConfig注册的路由。

亚洲必赢官网 20

再一次输入/account/login,发现已成功被ControllerFactory类拦截。

亚洲必赢官网 21

当今大家修改下ControllFactory类中ProcessRequest方法的代码,完成U本田UR-VL和类及类中艺术的投射。(注意,代码做了非凡容易的拍卖,大家借使忽略大小写因素,路由格式也和历史观MVC类似)

亚洲必赢官网 22亚洲必赢官网 23

 1 public void ProcessRequest(HttpContext context)
 2         {
 3             context.Response.Write(string.Format("ControllerFactory来拦截请求-> URL为: {0}",context.Request.RawUrl));
 4             context.Response.Write("<br/>");
 5 
 6             /**
 7              * 将拦截的URL地址分发给对应的Controller
 8              **/
 9             //简单处理,截取URL中第一个/和/之间的字符串做为要查找的Controller对象
10             string url = context.Request.RawUrl;
11             string actionURL = url.IndexOf('?') > 0 ? url.Substring(0, url.IndexOf('?')) : url.Substring(0);
12             string[] strArray = actionURL.Split('/');
13             //得到类名称
14             string targetClassName = (strArray[1] + "Controller");
15             string methodName = string.Empty;
16             if (strArray.Length > 2 && !string.IsNullOrEmpty(strArray[2]))
17                 methodName = strArray[2];//以'/'做分割,类名称后为方法名称
18             /**
19              * 从URL获取类名称之后,利用反射实现方法的调用。
20              **/
21             //获取Controller实例
22             object instance = Activator.CreateInstance(Type.GetType(string.Format("Demo4URLRouting.Controllers.{0}", targetClassName)));
23             if (instance != null)
24             {
25                 object outputObj = null;//方法输出内容
26                 if (string.IsNullOrEmpty(methodName) || instance.GetType().GetMethod(methodName) == null)
27                     methodName = "Index";//如果url没有输入方法或方法不存在,默认调用Index方法
28                 try
29                 {
30                     //调用实例方法
31                     outputObj = instance.GetType().GetMethod(methodName).Invoke(instance, null);
32                     context.Response.Write(outputObj);
33                 }
34                 catch(MissingMethodException mme)
35                 {
36                     context.Response.Write(string.Format("<font color='red'>Error! Method not Found!</font>  {0}",mme.Message));
37                 }
38             }
39         }

View Code

在代码中,实行了简约的url分析,获取类名和章程名,再通过反射机制,实现调用。

下一场,为了合作测试,大家在消除方案中新建1个Controllers文件夹,在该公文夹下新建2个类AccountController,代码如下

亚洲必赢官网 24亚洲必赢官网 25

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.";
        }

    }
}

View Code

AccountController类中定义了五个办法,Index()和HelloWorld()。然后大家透过浏览器举办走访

亚洲必赢官网 26

亚洲必赢官网 27

能够观察,通过在浏览器地址中,输入/Account,达成对AccountController类中Index方法的拜会;输入/Account/HelloWorld实现对AccountController类中的HelloWorld方法的造访。

到此,大家起先完结了在WebForms环境下,UPRADOL到类的照射。此进度的基本是handlers的布局和采取反射原理调用类中的方法。德姆o的欠缺是从未有过去破除大小写标题,未有更加灵敏的路由配置等。

那就是说难点来了,MVC中这一整套U大切诺基L映射的建制,是什么贯彻的吧?

MVC应用中规范的U帕杰罗L模式[Typical URL Patterns in MVC Applications]

  在MVC应用中,路由专业的UQashqaiL方式涵盖{controller}和 {action}占位符。

  当收到到八个呼吁时,它先被发送到UrlRoutingModule对象,再发送到MvcHandler
HTTP处理程序。MvcHandler
HTTP处理程序分明要求实践的控制器,通过给U奇骏L中的controller值添加”Controller”后缀从而鲜明将拍卖这一次请求的控制器类型名称。U帕杰罗L中的action值鲜明调用的处理办法。

  例如,U奥迪Q5L路径 /Products会被映射成ProductsController控制器。action参数的值是被调用的处理方式的称谓。UCR-VL路径/Products/show的照射结果将会是调用类ProductsController 的艺术Show。

  下表给出了默许的U陆风X8L格局和它们能处理的UTucsonL请求示例。

默认URL模式

匹配URL示例

{controller}/{action}/{id}

http://server/application/Products/show/beverages

{resource}.axd/{*pathInfo}

http://server/application/WebResource.axd?d=…

  路由使用方式 {resource}.axd/{*pathInfo} 来阻止对网络文件的伸手,例如WebReource.axd,ScriptResource.axd被传送给三个控制器。

  对于IIS柒.0,能够绝不扩大名。对于IIS陆.0,你无法不将扩展名.mvc添加到UCR-VL情势,如下所示:{controller}.mvc/{action}/{id}

MVC伍 U库罗德L映射机制

实质上,在写本篇小说在此以前,小编翻看了大气网上关于MVC的素材,发现大多数对MVC映射机制(也叫MVC路由体制)的叙述都相当笼统。

看似不懂装懂,可能让您去领略Model-View-Controller的叁层,什么工作分别,也许说了半天说一群废话。。。笔者是讨厌的。如若单单是解释微软MSDN上能查到的东西?那您的分解意义在哪儿?不说了,泡沫新闻太多了。

在摸底MVC U陆风X8L映射机制这一套原理以前,你首先要打听ASP.NET Routing。
ASP.NET Routing是.NET的一套独立组件。总的来说,它能够做两件事情:

1. 将UEnclaveL请求地址的片段转交到handler处理;

  1. 构造(创建)URL地址。

Routing方今的音讯实在太少,感兴趣的能够在MSDN.aspx)上做始发询问。总的来说,Routing做了我们眼下模拟做的享有工作,而且不要置疑,做的更加好更加强劲。

在MVC中,从U猎豹CS六L到Controller,简要进度大约是这么:

URL –>  RouteData对象 –> MvcHandler对象
–> IControllerFactory接口 –> Controller 

本条进程很复杂,要详细解说其经过,推断要三篇小说以上的篇幅。那里就不再解说。

MVC框架中,RouteConfig类中那段代码已经做了U汉兰达L到Controller映射的具备工作。你所急需做的,只是相配Controller了。

亚洲必赢官网 28亚洲必赢官网 29

    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 }
            );
        }
    }

View Code

3、      为Web Forms应用程序添加路由[Add Routes to a Web Forms Application]

  在Web
Form应用中,你能够应用类RouteCollection的方法MapPageRoute(String,
String,
String) 制造路由。方法MapPageRoute创建Route对象并将其拉长RouteCollection对象中。你供给为Route对象在参数在钦命1些本性,用来传给方法MapPageRoute。

  经常状态下,你在艺术中增进的路由会被Global.asax文件中Application_Start 方法处理器调用。那种艺术确定保障了那个路由在应用程序运营时可以符合规律调用。它也同意你在为应用程序做单元测试时可径直调用该方法。当你在做单元测试时假设想要间接调用3个措施,该办法在注册时就无法不是静态(Visual
Basic中Shared)且有2个RouteCollection参数。

  下例中示范了Global.asax文件中添加三个Route对象,该对象定义了action和categoryName八个参数。U奇骏L中还定义了1个被定向到名叫Categories.aspx的大体页面。

亚洲必赢官网 30亚洲必赢官网 31

protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx");
}

View Code

总结

本篇小说首要讲述了ASP.NET
MVC中的UCR-VL映射机制。先是透过在WebForms中模仿UPRADOL映射,让初我们有三个直观的认识。然后不难的介绍了MVC中U奥迪Q5L映射的建制。由于篇幅所限,在介绍U智跑L映射机制时,只做了归纳的阐释。因为知识量不小,而且提出读者要有ASP.NET
Routing组件的基础。关于Routing组件,现在有空的话,我再单独写小说来讲。

在下1篇文章中,小编将讲述Controller的实际利用及扩张,项目中Controller扮演的剧中人物。敬请期待。

正文原始地址。

四、      为MVC应用程序添加路由[Adding Routes to an MVC Application]

  在MVC应用程序中,假诺你利用MVC实现控制器的预约,即派生自类ControllerBase且以“Controller”结尾命名,那么您根本不供给搬运添加路由。预配置的路由将会进行你完成的支配器类中的处理办法。

  即便您希望在MVC应用程序中添加自定义的路由,你能够行使方法MapRoute(RouteCollection,
String,
String) 来取代方法MapPageRoute(String,
String,
String)。

  上边示例中示范在Global.asax文件中开创私下认可MVC路由的代码,正是Visual
Studio中MVC应用程序的类型模板。

亚洲必赢官网 32亚洲必赢官网 33

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

        routes.MapRoute(
            "Default",                                              // Route name 
            "{controller}/{action}/{id}",                           // URL with parameters 
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

View Code

5、      为U福特ExplorerL参数设置默许值[Setting Default Values for URL Parameters]

  当你定义七个路由时,你能够为参数钦赐三个暗中同意值。假使2个参数的值不在UPAJEROL中,则选择默许值。给路由设置暗中同意值时是给类Route的属性Defaults钦定3个字典对象。下例演示了如何运用格局MapPageRoute(String,
String, String, Boolean,
RouteValueDictionary)添加三个暗含暗中同意值的路由。

亚洲必赢官网 34亚洲必赢官网 35

void Application_Start(object sender, EventArgs e) 
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx",
        true,
        new RouteValueDictionary 
            {{"categoryName", "food"}, {"action", "show"}});
}

View Code

  下图中示范了ASP.NET路由拍卖UHavalL请求,路由定义(categoryName的默许值为food,action暗许为show)和剖析结果:

URL

Parameter values

/Category

action = "show" (default value)

categoryName = "food" (default value)

/Category/add

action = "add"

categoryName = "food" (default value)

/Category/add/beverages

action = "add"

categoryName= "beverages"

  对于MVC应用程序,方法RouteCollectionExtensions.MapRoute的重载版本,如MapRoute(RouteCollection,
String, String, Object,
Object),允许你钦点暗许值。

陆、      UPAJEROL情势中拍卖可变多少片断[Handling a Variable Number of Segments in a URL Pattern]

  有时候你必须处理包罗可变个数的U昂CoraL片断的ULANDL请求。当你定义2个路由时,你能够钦赐当一个U奥迪Q五L拥有比形式中还要多的片断时,额外的片断会被用作最终一个片断对待。你要求为最终3个参数添加多少个星号(*)来用这种措施处理额外的片断。那被称作全相配(catch-all)参数。包含全相配参数也将协作最终参数不带任何值的U奥迪Q三L。下例呈现3个方可包容不恐怕显明片断长度的路由方式。

  query/{queryname}/{*queryvalues}

  下图中示范了ASP.NET路由拍卖ULX570L请求,路由定义和剖析结果。

URL

Parameter values

/query/select/bikes/onsale

queryname = "select"

queryvalues = "bikes/onsale"

/query/select/bikes

queryname = "select"

queryvalues = "bikes"

/query/select

queryname = "select"

queryvalues = Empty string

七、      为路由添加封锁[Adding Constraints to Routes]

  路由方式中除了定义了可相配U中华VL请求的参数个数,还足以钦点那个参数的值须求满意的一些约束。如若三个ULacrosseL中的参数值不切合一个路由的牢笼,那么此路由不会处理该请求。你添加的封锁原则是为了确保UBMWX5L参数中带有的值能在你的应用程序中工作。

  约束原则是用正则表达式或落到实处了接口IRouteConstraint的对象来定义。当你将一条路由添加进Routes 集合时,你能够增伊利含验证测试的指标RouteValueDictionary封锁规范。字典中的键唯一标识符合约束原则的参数。字典中的值既可以是切合正则表达式的字符串,也能够是促成接口IRouteConstraint的对象。

  要是您提供3个字符串,路由会将它当作符合正则表达式的值,并调用Regex类的IsMatch()方法检查该参数值是或不是切合规则。正则表明式总是不区分轻重缓急写检讨。

  假若你提供了二个IRouteConstraint对象,ASP.NET路由调用IRouteConstraint目的的Match()方法来检查参数值是还是不是合法。Match()方法再次回到布尔值来申明参数值是还是不是合法。

  下例中示范怎么着行使方式MapPageRoute 添加一条路由,并为参数locale和year添加约束。(MVC应用程序中,使用办法MapRoute。)

亚洲必赢官网 36亚洲必赢官网 37

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx",
        true,
        new RouteValueDictionary 
            {{"categoryName", "food"}, {"action", "show"}},
        new RouteValueDictionary 
            {{"locale", "[a-z]{2}-[a-z]{2}"},{"year", @"\d{4}"}}
       );
}

View Code

  当路由拍卖ULacrosseL请求时,例子中路由的概念和剖析后的结果如下表所示:

URL

Result

/US

No match. Both locale and year are required.

/US/08

No match. The constraint on year requires 4 digits.

/US/2008

locale = "US"

year = "2008"

捌、      路由不起功效的景色[Scenarios When Routing Is Not Applied]

  在壹些处境下,ASP.NET路由即使可用也不会处理请求。这节将介绍三种路由不会处理请求的情事。

UENCOREL格局相配二个有效的物理文件[A Physical File is Found that Matches the URL Pattern]

  私下认可意况下,路由不会处理请求时,将其映射到Web服务器上1个已存在的情理文件。例如,假设存在1个物理文件Products/Beverages/Coffee.aspx,路由就不会处理请求

  假如你希望路由能处理全部请求,就算请求指向3个文件,你能够透过安装对象RouteCollection的属性RouteExistingFiles为true来重写暗中同意行为。当您将那几个值设置为true则全体与定义路由情势相配的呼吁都会被路由拍卖。

显式禁止使用路由[Routing Is Explicitly Disabled for a URL Pattern]

  你也得以指明路由不处理有个别U安德拉L请求。定义2个路由并指明由类StopRoutingHandler拍卖该方式,以阻挡路由拍卖某个请求。当三个请求被亚洲必赢官网,StopRoutingHandler目的处理时,StopRoutingHandler对象块会为呼吁添加1些额外的新闻。相反,这一个请求会被用作2个ASP.NET页面、Web服务大概别的ASP.NET终端处理。你能够使用格局RouteCollection.Ignore(MVC应用程序中RouteCollectionExtensions.IgnoreRoute)来创立使用类 StopRoutingHandler的路由。下边演示怎样阻止对WebResource.axd文件的乞求。

亚洲必赢官网 38亚洲必赢官网 39

public static void RegisterRoutes(RouteCollection routes)
{
  routes.Ignore("{resource}.axd/{*pathInfo}");
}

View Code

  U陆风X8L是哪些被路由十二分的[How URLs Are Matched to Routes]

  当路由初叶拍卖U大切诺基L请求时,它为尝试着将呼吁相称到一条路由规则上。一条路由规则能无法相称UBMWX3L请求取决与以下原则:

    • 在您的档次中是否含有自定义的路由规则可能私下认可路由。
    • 集合Routes中添加路由规则的壹壹。
    • 为路由规则添加的暗中同意值。
    • 为路由规则添加的牢笼。
    • 是不是定义了万分对物理文件请求的路由。

  为了防止不适当的路由处理了请求,在定义路由规则时必然要思念全部那个规范。集合 Routes中Route目的出现的11也应密切惦记。路由集合中从第3项到最后壹项依次尝试的路由相称。当有一个金童玉女成功,不再对继续路由尝试相称。平常,添加路由时应先添加最现实的,最终添加最不明显的条条框框。

  例如你添加了如下路由规则:

    •   路由规则一,{controller}/{action}/{id}
    •   路由规则贰, products/show/{id}

  路由二绝不会处理请求,因为路由一会起初尝试相配,并且与路由二金童玉女的请求在它上边也再而3能够干活。例如请求

    •   controller is products.
    •   action is show.
    •   id is bikes.

  当呼吁的参数缺少时,暗许值就能起效果。不过,它们大概会合作到不要你所愿的乞请。例如,要是添加如下两条路由规则:

    •   路由一:{report}/{year}/{month},year,month带有暗中同意值。
    •   路由二:{report}/{year},year有暗中认可值。

  路由二将绝无处理请求的火候。路由1盼望能按月度相配,而路由2则指望是按年度。可是,路由第11中学的私下认可值会让全体相称路由2的乞请在路由第11中学也能做事。

  你能够在路由中带有常量来防止那种歧义,例如annual/{report}/{year}和monthly/{report}/{year}/{month}。

  假若三个U悍马H2L不能够相称到在RouteTable集合中的任何1个Route对象,ASP.NET路由将不会处理该请求。

玖、      从路由创造U凯雷德L[Creating URLs from Routes]

  就算你想要创立多少个链接到您站点页面包车型大巴超链接,你能够选取UHavalL格局编制程序创制符合路由的U福睿斯L。当你改改了路由形式,U昂CoraL会自动相称到新的情势上。

10、      在路由页面访问U奥迪Q⑤L参数[Accessing URL Parameters in a Routed Page]

参见:

拾壹、      配置路由环境[Configuration Settings for Routing]

  ASP.NET中,要让应用程序支持路由作用,须要充裕如下配置:

亚洲必赢官网 40亚洲必赢官网 41

<configuration>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <!-- more -->
    </modules>
  </system.webServer>
</configuration>

View Code

  当runAllManagedModulesForAllRequests为true时,如下URL

  不过,IIS7的翻新导致不必添加配置项runAllManagedModulesForAllRequests,因为它自然就匡助ASP.NET路由成效。

  假若你的站点运维在IIS七且IIS已履新,你就不用安装该配置项为true。事实上,并不推荐设置它,因为它为有着请求扩张了不必要的操作。假如设置该配置为true,全部请求,包罗.htm,.jpg和其它静态文件都会透过ASP.NET请求通道。

  默认runAllManagedModulesForAllRequests为false。假诺网站配置文件中未有分明将其安装为true,而你又在未设置SP一的Windows
7,不含有必要更新的IIS柒中运转你的网址。
结果就是,你会看出路由不会做事的谬误提醒。假诺路由中设有一些题材,你能够尝试上边包车型的士艺术:

    •   将Windows 七更新到SP一,因为它添加了IIS七的创新。
    •   安装微软件在原先文章中的描述的翻新。
    •  
      在Web.Config文件中装置runAllManagedModulesForAllRequests为true。注意那会添加①些额外开支。

10二、      ASP.NET路由与安全性[ASP.NET Routing and Security]

  授权规则可接纳于独立映射的路由U中华VL或同时映射的路由USportageL和物理ULacrosseL。例如,授权规则能够表明全部用户都足以访问以发轫Category的U奥迪Q7L,可是只有管理员才能访问Categories.aspx页面。固然路由UBMWX5L形式contoso.com/Category/{controller}/{action} 映射到大体地址contoso.com/Categoriespage.aspx,你不得不为路由地址添加授权规则,当用叁个路由地址请求过之后,全部用户都被允许可访问Categoriespage.aspx。不过,当使用物理地址请求之后,唯有管理才有权力访问。

  私下认可意况下,授权规则应用于路由地址和大体地址。

拾3、      ASP.NET Web Form和路由安全性[ASP.NET Web Forms and Route Security]

  在ASP.NET
Web窗体应用程序中,你不该将站点的安全性全寄托在路由授权规则,因为它们或许留下一些未珍视处理的大体地址。

拾四、      ASP.NET MVC和路由安全性[ASP.NET MVC and Route Security]

  你不能够选拔路由或web.config文件保障MVC应用程序的安全性。唯一能保障MVC应用安全的做法是给全体控制器选取脾性 AuthorizeAttribute ,并在报到和注册的艺术(action)上行使个性AllowAnonymousAttribute 。

  扩充请查看:

十五、      参考类[Class Reference]

Class

Description

Route

Represents a route in a Web Forms or MVC application.

DynamicDataRoute

Represents a route in a Dynamic Data application.

RouteBase

Serves as the base class for all classes that represent an ASP.NET route.

RouteTable

Stores the routes for an application.

RouteCollection

Provides methods that enable you to manage a collection of routes.

RouteCollectionExtensions

Provides additional methods that enable you to manage a collection of routes in MVC applications.

RouteData

Contains the values for a requested route.

RequestContext

Contains information about the HTTP request that corresponds to a route.

StopRoutingHandler

Provides a way to specify that ASP.NET routing should not handle requests for a URL pattern.

PageRouteHandler

Provides a way to define routes for Web Forms applications.

RouteValueDictionary

Provides a way to store route ConstraintsDefaults, and DataTokensobjects.

VirtualPathData

Provides a way to generate URLs from route information.

十六、      ASP.NET路由VS URL重写[ASP.NET Routing versus URL Rewriting]

  ASP.NET路由与U宝马X3L重写分歧。U奇骏L重写形式处理到达的央浼时,先修改其U福睿斯L再将请求发送至Web页面。例如,二个应用程序中可能接纳U路虎极光L重写将/Products/Widgets/修改为/Products.aspx?id=四。同时,U奥德赛L重写的性格是未有基于你的格局创建U库罗德L的API。使用UCR-VL重写,假若你须要性情U帕杰罗L规则,你不得不手动更新具有相关联的超链接。

  使用ASP.NET路由,在拍卖到达的请求时U纳瓦拉L不会发生变化,因为路由功用或者从UOdysseyL中领取值。当你须要成立二个U宝马7系L时,给三个方式传入参数值就能为您生成U景逸SUVL。修改U冠道L规则,只须求调动三个地点,你在应用程序中开创的持有链接都会活动使用新规则。

 

  源地址:

网站地图xml地图