关于MVC RouteExistingFiles疑问后续

前两天写了《关于MVC RouteExistingFiles疑问》,本来希望寻求大佬快速解答,奈何无人问津。

只能查看.NET 源代码,可以使用反编译工具(我用IL spy),也可以在线查看微软提供的:https://referencesource.microsoft.com/
MVC的路由会走UrlRoutingModule,代码在 System.Web/Routing/UrlRoutingModule.cs 中

RouteData routeData = RouteCollection.GetRouteData(context);
GetRouteData的源代码:
 public RouteData GetRouteData(HttpContextBase httpContext) {
            if (httpContext == null) {
                throw new ArgumentNullException("httpContext");
            }
            if (httpContext.Request == null) {
                throw new ArgumentException(SR.GetString(SR.RouteTable_ContextMissingRequest), "httpContext");
            }
 
            // Optimize performance when the route collection is empty.  The main improvement is that we avoid taking
            // a read lock when the collection is empty.  Without this check, the UrlRoutingModule causes a 25%-50%
            // regression in HelloWorld RPS due to lock contention.  The UrlRoutingModule is now in the root web.config,
            // so we need to ensure the module is performant, especially when you are not using routing.
            // This check does introduce a slight bug, in that if a writer clears the collection as part of a write
            // transaction, a reader may see the collection when it's empty, which the read lock is supposed to prevent.
            // We will investigate a better fix in Dev10 Beta2.  The Beta1 bug is Dev10 652986.
            if (Count == 0) {
                return null;
            }
 
            bool isRouteToExistingFile = false;
            bool doneRouteCheck = false; // We only want to do the route check once
            if (!RouteExistingFiles) {
                isRouteToExistingFile = IsRouteToExistingFile(httpContext);
                doneRouteCheck = true;
                if (isRouteToExistingFile) {
                    // If we're not routing existing files and the file exists, we stop processing routes
                    return null;
                }
            }
 
            // Go through all the configured routes and find the first one that returns a match
            using (GetReadLock()) {
                foreach (RouteBase route in this) {
                    RouteData routeData = route.GetRouteData(httpContext);
                    if (routeData != null) {
                        // If we're not routing existing files on this route and the file exists, we also stop processing routes
                        if (!route.RouteExistingFiles) {
                            if (!doneRouteCheck) {
                                isRouteToExistingFile = IsRouteToExistingFile(httpContext);
                                doneRouteCheck = true;
                            }
                            if (isRouteToExistingFile) {
                                return null;
                            }
                        }
                        return routeData;
                    }
                }
            }
 
            return null;
        }

说实话,没看出来什么。

好吧,依稀记得可以调试源代码,也是查了一下,配置VS,下载PDB文件,就能调试了。具体设置,微软地址:https://referencesource.microsoft.com/setup.html

有类似需求的同学可以参考这篇文章,能详细点:https://blog.csdn.net/egman/article/details/78281424

然而,不知道什么原因,我用的VS2017怎样都无法进入源代码。

 

于是一个问题就变成了两个问题。

 

于是又搜其他办法,发现JB的DotPeek软件可以,官方地址:https://www.jetbrains.com/decompiler/

这里就不详细介绍操作了,可以参考园友博客:https://www.cnblogs.com/herenwei-wayne/p/5595429.html

run起来,终于进入到源码中GetRouteData方法中了

依次请求静态资源地址,进行调试:

①/a.jpg:匹配到默认路由“controller/action/id”,controller是a.jpg
②/Theme/a.jpg:匹配到默认路由“controller/action/id”,controller是Theme,Action是a.jpg
③/Areas/Admin/a.jpg:匹配到默认路由“controller/action/id”...
④/Areas/Admin/Theme/a.jpg:未匹配到任何路由,renturn

 

之前的理解是,

1.配到到路由,比如输入a/b/1,但未找到对应的控制器等,提示不存在

2.未匹配到路由,比如输入a/b/c/d/e/f,也会提示不存在

 

但事实上,

1.配到到路由,比如输入a/b/1,但未找到对应的控制器等,提示不存在(程序可以捕获)

2.未匹配到路由,比如输入a/b/c/d/e/f,路由中return,交由IIS处理

 

所以,如果利用此特性做文件夹的访问控制,一定要设置对应文件夹的路由规则,然后处理。

posted @ 2019-01-27 14:43  talentzemin  阅读(242)  评论(0编辑  收藏  举报