首页 > 代码库 > 对磁盘文件的请求进行路由
对磁盘文件的请求进行路由
url中如果有对静态文件的请求,也可以对它进行路由。例如,图片、静态html文件、JavaScript库等。
在前面例子的解决方案中,在Content文件夹中创建一个叫做“StaticContent.html”的文件。
<html> <head> <title>Static HTML Content</title> </head> <body> this is the static html file (~/Content/StaticContent.html) <h2>你现在使用的不是Chrome浏览器,请使用Chrome浏览器访问</h2> </body> </html>
默认情况下,路由系统会先考察一个url是否直接匹配磁盘文件。如果有匹配,就直接访问到这个磁盘文件,默认就不使用路由,包括路由中的约束都不对此访问起作用。例如,对上面的文件,在默认情况下,在任一浏览器中直接给出url:
"~/Content/ContentStatic.html"
就可以直接访问到。
如果希望在检查磁盘文件之前,先进行路由匹配,可以将RouteExistingFils属性设置为true,例如:
public static void RegisterRoutes(RouteCollection routes) { routes.RouteExistingFiles = true; routes.MapRoute("DiskFile", "Content/StaticContent.html", new { Controller = "Account", Action = "LogOn" }, new { customConstraint = new UserAgentConstraint("Chrome") }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { Controller = "Home", Action = "Index", id = UrlParameter.Optional }, new { Controller="^H.*", Action="^Index$|^About$", httpMethod = new HttpMethodConstraint("GET")}, new[] { "_11_3URLTestDemo.Controllers" }); }
上面的new { customConstraint = new UserAgentConstraint("Chrome") }使用了自定义的一个类UserAgentConstraint来生成一个实例,通过判断客户端浏览器发出请求时,传递过来的状态字符串中是否包含特定子串,来限定指定的浏览器。客户端浏览器的状态字符串是通过属性httpContext.Request.UserAgent传递过来的。因此,在当前项目中11-3URLTestDemo中新建一个名为“Infrastructure”的文件夹,在此文件夹中添加一个类库文件UserAgentConstraint.cs,内容如下:
namespace _11_3URLTestDemo.Infrastructure { public class UserAgentConstraint:IRouteConstraint { private string requiredUserAgent; public UserAgentConstraint(string agentParam) { requiredUserAgent = agentParam; } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { return httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(requiredUserAgent); } } }
当然,前面在Global.asax中使用该类来生成实例时,就需要using _11_3URLTestDemo.Infrastructure;
在Global.asax的RegisterRoutes中,首先设置
routes.RouteExistingFiles = true;
表示对磁盘文件的url请求要先进行路由匹配,路由不匹配时才对该磁盘文件直接访问。
接下来设置了对该磁盘文件的路由:
routes.MapRoute("DiskFile", "Content/StaticContent.html", new { Controller = "Account", Action = "LogOn" }, new { customConstraint = new UserAgentConstraint("Chrome") });
如果有url请求"~/Content/StaticContent.html",就会路由到Controller为Account,Action为LogOn的方法上进行执行,而且后面还有一个约束,就是客户端浏览器传递过来的状态字符串中要包含Chrome,也就是限定了只有客户端是使用的Chrome浏览器时,才做此路由,否则,就直接访问Content/StaticContent.html
通过这样的设置,就可以限定在对某一url请求时,根据客户端使用的浏览器不同,来做不同的处理。
在本例中,对于"~/Content/StaticContent.html"的请求,如果用户用的Chrome浏览器,则匹配路由,执行AccountController里的LogOn方法,如果用户用的是其他浏览器(比如ie),那么就直接给出对StaticContent.html文件的访问。
Chrome的 httpContext.Request.UserAgent "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36" string
ie10的httpContext.Request.UserAgent "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)" string
在实验过程中,上面的例子限定Chrome能够稳定执行。
但是在限定ie浏览器时,执行不稳定。例如,
routes.MapRoute("DiskFile", "Content/StaticContent.html", new { Controller = "Account", Action = "LogOn" }, new { customConstraint = new UserAgentConstraint("MSIE") });
企图限定客户端使用ie浏览器才匹配路由,否则直接给出对StaticContent.html的访问。实验时采用的ie10,可以看到上面给出的状态字符串,直接限定字符给IE是不行,给MSIE,但在执行过程中在UserAgentConstraint.cs的:
return httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(requiredUserAgent);
处设置断点,有时能中断,有时不能中断。路由也是有时匹配,有时不匹配,目前没有找到引起这个问题的原因。使用Chrome浏览器就很稳定,能中断,也能按约束正常路由匹配。