您的位置:首页 > 其它

深入了解Mvc路由系统

2016-03-05 11:10 381 查看
请求一个MVC页面的处理过程

1.浏览器发送一个Home/Index的链接请求到iis。iis发现时一个asp.net处理程序。则调用asp.net_isapi扩展程序发送asp.net框架

2.在asp.net的第七个管道事件中会遍历UrlRoutingModule中RouteCollection的RoteBase集合通过调用其GetRouteData方法进行路由匹配返回一个实现了IRoteHandler的类的对象,没有则返回null继续向下遍历

3.调用IRoteHandler的getIhttpHanderl获得实现了IhttpHandler的类的对象。再在11到12个事件管道调用其ProcessRequset执行处理逻辑将结果写入response

这里我们会发现很多个扩展点1.自定义RoteBase写入集合2.自定义IroteHandler3.自定义IhttpHandler

尝试自定一个RoteBase并添加到UrlRoutingModule的RoteBase集合中

publicclassMyRote:RouteBase
{
///<summary>
///此方法是处理请求是否跟当前路由匹配
///</summary>
///<paramname="httpContext"></param>
///<returns></returns>
publicoverrideRouteDataGetRouteData(HttpContextBasehttpContext)
{
//假如我们定义如果是谷歌用户则命中路由当前路由
if(httpContext.Request.UserAgent.IndexOf("Chrome")>=0)
{
RouteDatard=newRouteData(this,newMvcRouteHandler());
//假设命中了此路由解析获得请求控制器为Homeaction方法为Index
rd.Values.Add("controller","Home");
rd.Values.Add("action","MyRoteIndex");
returnrd;
}
returnnull;
}

///<summary>
///此方法在通过Url.action()的时候根据当前路由生成路径
///</summary>
///<paramname="requestContext"></param>
///<paramname="values"></param>
///<returns></returns>
publicoverrideVirtualPathDataGetVirtualPath(RequestContextrequestContext,RouteValueDictionaryvalues)
{
returnnewVirtualPathData(this,"Home/MyRoteIndex");
}
}
在RouteConfig添加到UrlRoutingModule的RouteCollection中


publicclassRouteConfig
{
publicstaticvoidRegisterRoutes(RouteCollectionroutes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
/***
*因为路由匹配是遍历匹配的所以我们写到第一个位置。否则可能会出现匹配到下面的路由
*添加到RoteBase集合。下面的方法是个扩展方法内部也是调用的add方法
***/
routes.Add("myRote",newMyRote.MyRote());
routes.MapRoute(
name:"Default",
url:"{controller}/{action}/{id}",
defaults:new{controller="Home",action="Index",id=UrlParameter.Optional}
);

}
}
这个时候我们用谷歌就会发现无论我们请求哪个页面都是调用Home/MyRoteIndex还有在视图页面通过@url.acton通过路由生成链接也是都是Home/MyRoteIndex

2.自己实现自己的RoteHandler和IhttpHandler


publicclassMyRoteHandler:IRouteHandler
{
publicIHttpHandlerGetHttpHandler(RequestContextrequestContext)
{
//返回我们自己的IttpHandler处理对象
returnnewMyIHttpHandler();
}
}

publicclassMyIHttpHandler:IHttpHandler
{

publicboolIsReusable
{
get{returntrue;}
}

/***
*我们之前说了在第11到12个事件管道是调用这个方法写入response
*MVC实现的IhttpHandler则是通过匹配的路由反射调用指定控制器的action方法再调用ActionrResult的ExcuteReuslt方法将结果写入response
*asp.net处理页面则是调用后台页类的ProcessRequset方法处理我们程序员写的逻辑了
***/
publicvoidProcessRequest(HttpContextcontext)
{
if(context.Request.UserAgent.IndexOf("Chrome")>=0)
{
context.Response.Write("当前是谷歌浏览器");
}
elseif(context.Request.UserAgent.IndexOf("MSIE")>=0)
{
context.Response.Write("当前是Ie浏览器");
}
else
{
context.Response.Write("其他浏览器");
}
}
}


///<summary>
///此方法是处理请求是否跟当前路由匹配
///</summary>
///<paramname="httpContext"></param>
///<returns></returns>
publicoverrideRouteDataGetRouteData(HttpContextBasehttpContext)
{
//方便调试则默认他是全部请求匹配此路由
if(true)
{
//这里的RoteHandler则返回我们自己的实现
RouteDatard=newRouteData(this,newMyRoteHandler());
//假设命中了此路由解析获得请求控制器为Homeaction方法为Index
rd.Values.Add("controller","Home");
rd.Values.Add("action","MyRoteIndex");
returnrd;
}
}

///<summary>
///此方法在通过Url.action()的时候根据当前路由生成路径
///</summary>
///<paramname="requestContext"></param>
///<paramname="values"></param>
///<returns></returns>
publicoverrideVirtualPathDataGetVirtualPath(RequestContextrequestContext,RouteValueDictionaryvalues)
{
returnnewVirtualPathData(this,"Home/MyRoteIndex");
}


因为都是匹配我们的自己实现的路由和返回我们自己的RoteHandelr最终结果是请求任何url都是执行我们自己的IttpHanler的处理逻辑的方法






                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: