MVC中的扩展点(一)路由上的扩展
来源:互联网 发布:华夏网络徐醒东 编辑:程序博客网 时间:2024/06/10 04:38
原文出处:http://www.cnblogs.com/xfrog/archive/2010/12/19/1910428.html
一、RouteBase
RouteBase是一个抽象类,包含两个抽象方法:GetRouteData用于检查请求上下文是否符合路由规则,如果符合返回一个RouteData对象,若不符合则返回null,UrlRoutingModule在在遍历Routes集合时,将调用此方法,如果方法返回非空,则终止遍历,并将返回的RouteData保存到请求上下文(RequestContext)中。GetVirtualPath方法用于检查指定的路由信息是否符合本路由规则,如果符合返回一个VirtualPathData对象,通过该对象可以获取响应的Url,如果不符合则返回null,通常我们通过MVC中的Html.RouteLink方法来生成Url时,此方法会遍历RoueTable.Routes中的路由对象,依次调用GetVirtualPath方法,直到方法返回非空。
下面我们将创建一个MyRoute类,该类将阻止IE浏览器方法网站。
1、首先,我们创建一个MVC2空应用程序项目,然后创建一个名为Home的控制器,在控制器中创建两个Action:Index表示网站首页,Limit表示一个显示限制信息的页面,如果浏览器为IE则会直接显示此页面类容。
2、创建Index和Limit活动所对应的视图。
显示行号 复制代码 ? Index.aspx
<div>
<h1>欢迎-!</h1>
</div>
显示行号 复制代码 ? Limit.aspx
<div>
不允许IE浏览器访问
<%= Html.RouteLink("MyRoute", new {applay="IE" }) %>
<%= Html.RouteLink("Route", new { controller = "Home", action = "Index" })%>
</div>
3、创建一个MyRoute类,让其继承自RouteBase,重写GetRouteData和GetVirtualPath方法:
显示行号 复制代码 ? MyRoute.cs
public class MyRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
if (httpContext.Request.UserAgent.IndexOf("MSIE")>=0 )
{
RouteData rd = new RouteData(this, new MvcRouteHandler());
rd.Values.Add("controller", "Home");
rd.Values.Add("action", "Limit");
return rd;
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
if (values.ContainsKey("applay") && values["applay"] == "IE")
{
return new VirtualPathData(this, "IE/Index");
}
return null;
}
}
4、打开Global.asax.cs文件,找到RegisterRoutes方法,将我们的MyRoute注册到RouteTable.Routes集合中,注意添Route的顺序很重要,UrlRoutingModule在遍历时是按照添加顺序进行的,所以未保证MyRoute规则有效,必须将其放到第一个位置。注意MapRoute方法是MVC框架对RouteCollection的扩展,用于添加一个Route对象到集合中,本质上内部也是调用的Add方法。
显示行号 复制代码 ? MvcApplication
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add("myRoute",new MyRoute());
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
启动调试,如果是IE浏览器,则会显示“不允许IE浏览器访问”,另外,请注意看MyRoute与Route连接的地址,显然MyRoute的地址是通过MyRoute类产生的,而Route地址是通过Route默认路由对象产生的。
二、IRouteHandler
UrlRoutingModule在获取到合适的RouteData后,将通过其RouteHandler属性来获取实际的IHttpHandler对象,通过IHttpHandler来处理请求。在MVC中,已经实现了一个RouteHandler,即MvcRouteHandler,在上例中我们的GetRouteData方法使用的即是MvcRouteHandler。
IRouteHandler接口只有一个方法:GetHttpHandler它返回一个IHttpHandler对象。也就是说最终页面的生成是在IHttpHandler对象中实现的。对应于MVC,MvcRouteHandler的GetHttpHandler方法返回一个MvcHandler对象,MvcHandler对象负责调用合适的Controller与Action方法。
下面我们沿用上例,实现一个IERouteHandler,通过这个Handler来处理来自IE浏览器的请求。
1、添加一个IERouteHandler类,继承自IRouteHandler,实现其GetHttpHandler方法,返回一个IEHandler对象。
显示行号 复制代码 ? IERouteHandler
public class IERouteHandler : IRouteHandler
{
#region IRouteHandler Members
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new IEHandler();
}
#endregion
private class IEHandler : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("不允许IE浏览器访问");
}
#endregion
}
}
2、修改MyRoute的GetRouteData方法,将之前的MvcRouteHandler修改为IERouteHandler
显示行号 复制代码 ? MyRoute
public override RouteData GetRouteData(HttpContextBase httpContext)
{
if (httpContext.Request.UserAgent.IndexOf("MSIE")>=0 )
{
//RouteData rd = new RouteData(this, new MvcRouteHandler());
//rd.Values.Add("controller", "Home");
//rd.Values.Add("action", "Limit");
RouteData rd = new RouteData(this, new IERouteHandler());
return rd;
}
return null;
}
三、IRouteConstraint
IRouteConstraint接口由Route类的Constraints属性使用,用于判断当前的Url是否符合路由的约束条件。Route已经实现了一个HttpMethodConstraint用于限制请求方法,例如:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { method = new HttpMethodConstraint("POST") }
);
表明此项路由规则必须是POST请求才有效,即就算Url为Home/Index形式,符合Url规则,但是如果请求是通过的GET方法,那此项规则也不满足,明显,Route的GetRouteData方法中会检查所有的约束条件,如果某项约束条件不满足仍然会返回null。
IRouteConstraint接口有一个Match方法,如果请求上下文符合约束返回true否则返回false。
沿用上例,现在我们通过IRouteConstraint来限制IE浏览器的访问:
1、新建类IERouteConstraint,实现其Match方法:
显示行号 复制代码 ? IERouteConstraint
public class IERouteConstraint : IRouteConstraint
{
#region IRouteConstraint Members
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return !(httpContext.Request.UserAgent.Contains("MSIE"));
}
#endregion
}
2、修改Global.asax.cs的RegisterRoutes方法,屏蔽掉之前加入的MyRoute规则,然后修改默认的MapRoute:
显示行号 复制代码 ? MvcApplication
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// routes.Add("myRoute",new MyRoute());
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { ie = new IERouteConstraint() }
);
}
启动调试,如果是IE浏览器,将显示一个无法找到资源的404错误。
- MVC中的扩展点(一)路由上的扩展
- MVC中的扩展点(二)路由上的扩展
- MVC中的扩展点(一)路由系统简介
- MVC中的扩展点:ActionResult
- MVC 路由扩展 实例
- MVC中的扩展点(二)控制器工厂
- MVC中的扩展点(三)过滤器
- MVC中的扩展点(六)ActionResult
- MVC中的扩展点(三)控制器工厂
- MVC中的扩展点(四)过滤器
- MVC中的扩展点(五)方法选择器
- MVC中的扩展点(六)ActionResult
- MVC中的扩展点(八)模型绑定
- MVC中的扩展点(九)验证
- MVC中的扩展点(十)辅助方法
- MVC 扩展点:
- ASP.NET MVC路由扩展:路由映射
- ASP.NET MVC路由扩展:路由映射
- 设计文档编写思路
- 关于计算机编程的两件事
- GPT分区表 管理 自动挂载于2T的分区
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用43
- vs2008 下编译jrtplib-3.9.0成功
- MVC中的扩展点(一)路由上的扩展
- 将基于MFC的对话框应用程序修改为服务程序
- Ubuntu 下shell 批处理文件
- 职场的修炼(转)
- android XML文件解析之 SAX解析方法
- 关于iOS应用开发
- Lapack 资料参考
- 游标的应用
- C++ 传递数组的问题