ASP.NET MVC - 路由系统
2020-11-15 00:46
标签:http class div code tar ext string art get tab ble ASP.NET
MVC的请求URL不再对应于传统ASP.NET程序的ASPX文件物理地址,而是把请求映射到一个控制器(Controller)类的方法(Action)上,Controller、Action再加上参数构成ASP.Net
MVC请求的Url。下面我们来看下路由系统的主要对象。 ASP.NET
MVC框架的路由实质是从传统ASP.NET管道扩展HttpModule而来,这个模块正是UrlRoutingModule。通过反编译可以看到UrlRoutingModule注册了HttpApplication对象的PostResolveRequestCache事件而最终调用PostResolveRequestCache(HttpContextBase
context),就是在这个事件中ASP.Net MVC完成了路由的主要工作,首先RouteCollection 通过调用GetRouteData
方法依次调用集合中Route对象的GetRouteData方法,直到找到一个与Url相匹配的Route对象并返回RouteData,然后通过RouteData得到RouteHandler。在构造完RequestContext对象后调用RouteHandler的GetHttpHandler方法最终得到一个HttpHandler。下面列出了主要代码。 Route类继承于RouteBase,Constraints、DataTookens、Defaults三个属性分别保存了Url的约束,控制器的命名空间和URL默认值。RouteHandler属性默认是通过构造函数传入的MVCRouteHandler。GetRouteData(HttpContextBase
httpContext)方法继承于RouteBase,如果URL匹配则返回RouteData对象。另外,ASP.NET MVC
5.0的Route对象多出了一个于RouteCollection的RouteExistingFiles同名属性,这两个对象中的属性协同控制是否对已存在文件使用路由。 RouteBase的两个抽象方法负责一进一出,GetRouteData方法用来从URL获取RouteData,GetVirtualPath方法则用在通过路由数据生成URL的场景。RouteData对象可以说是对RouteBase和RouteHandler的封装,它存储了路由所需的所有信息。 RouteCollection是RouteBase对象的集合,它做为RouteTable类的静态属性Routes而存在,在应用程序Application_Start事件中所有的路由将注册到这个集合中。RouteExistingFiles属性指示路由操作是否应处理与现有文件匹配的
URL,其默认值是false,这意味着ASP.NET
MVC也可以与传统aspx页面集成工作,特别是正在从WebPage迁移到MVC的项目。我们打开一个ASP.NET MVC
的示例项目可以看到路由是如何注册到路由表的。 在RouteCollectionExtensions类中MapRoute方法有多个重载,下面列出最后一个方法的主要代码,我们可以看到Route对象是如何被构造的并且知道Route类的各个属性存储了什么。 对URL约束我们通过RouteCollection类扩展方法MapRoute的参数constraints传入,以示例项目{controller}/{action}/{id}的URL为例,如果我们想要限制"id"只能为数字,那么我们会像下面这样传入constraints对象。 实际上我们不仅可以传入正则表达式也可以传入一个实现了IRouteConstraint接口的对象,这个接口有且只有唯一个Match方法,它的签名如下。parameterName对应了属性的名字,在里为"id",这个方法中我们可以拿到HttpContext、Route和RouteValueDictionary这几个重要对象。在Route对象的ProcessConstraint方法中如果传入的是一个实现了IRouteConstraint方法的对象,会调中它的Match方法,我们可以实现这个接口来处理更复杂的约束。 ASP.NET MVC - 路由系统,布布扣,bubuko.com ASP.NET MVC - 路由系统 标签:http class div code tar ext string art get tab ble 原文地址:http://www.cnblogs.com/burnsyzhao/p/3695544.htmlUrlRoutingModule
public
virtual
void
PostResolveRequestCache(HttpContextBase context)
{
RouteData routeData =
this
.RouteCollection.GetRouteData(context);
IRouteHandler routeHandler = routeData.RouteHandler;
RequestContext requestContext =
new
RequestContext(context, routeData);
context.Request.RequestContext = requestContext;
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
if
(!(httpHandler
is
UrlAuthFailureHandler))
{
context.RemapHandler(httpHandler);
return
;
}
}
Route
public
class
Route: RouteBase
{
public
RouteValueDictionary Constraints {
get
;
set
; }
public
RouteValueDictionary DataTokens {
get
;
set
; }
public
RouteValueDictionary Defaults {
get
;
set
; }
public
IRouteHandler RouteHandler {
get
;
set
; }
public
Route(
string
url, IRouteHandler routeHandler)
public
Route(
string
url, RouteValueDictionary defaults, IRouteHandler routeHandler)
public
Route(
string
url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
public
Route(
string
url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
}
RouteBase
public
abstract
class
RouteBase
{
public
abstract
RouteData GetRouteData(HttpContextBase httpContext);
public
abstract
VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}
RouteCollection
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 }
);
}
public
static
class
RouteCollectionExtensions
{
public
static
Route MapRoute(
this
RouteCollection routes,
string
name,
string
url)
public
static
Route MapRoute(
this
RouteCollection routes,
string
name,
string
url,
object
defaults)
public
static
Route MapRoute(
this
RouteCollection routes,
string
name,
string
url,
object
defaults,
object
constraints)
public
static
Route MapRoute(
this
RouteCollection routes,
string
name,
string
url,
string
[] namespaces)
public
static
Route MapRoute(
this
RouteCollection routes,
string
name,
string
url,
object
defaults,
string
[] namespaces)
public
static
Route MapRoute(
this
RouteCollection routes,
string
name,
string
url,
object
defaults,
object
constraints,
string
[] namespaces)
{
Route route =
new
Route(url,
new
MvcRouteHandler())
{
Defaults = RouteCollectionExtensions.CreateRouteValueDictionary(defaults),
Constraints = RouteCollectionExtensions.CreateRouteValueDictionary(constraints),
DataTokens =
new
RouteValueDictionary()
};
if
(namespaces !=
null
&& namespaces.Length > 0)
{
route.DataTokens[
"Namespaces"
] = namespaces;
}
routes.Add(name, route);
return
route;
}
}
IRouteConstraint
routes.MapRoute(
"Product"
,
"Product/{productId}"
,
new
{controller=
"Product"
, action=
"Details"
},
new
{id =
@"\d+"
});
public
interface
IRouteConstraint
{
bool
Match(HttpContextBase httpContext, Route route,
string
parameterName, RouteValueDictionary values, RouteDirection routeDirection);
}