• [ASP.NET 2.0]PageParser.GetCompiledPageInstance中的一个Bug及解决方法


         最近在将博客园的程序迁移到ASP.NET 2.0,本来在本机虚拟目录中运行时可以正常访问首页,比如:http://localhost/blog。
         可到在服务器上测试时,访问地址:http://test.cnblogs.com,却出现“Object reference not set to an instance of an object”异常,异常产生于 System.Web.UI.PageParser.GetCompiledPageInstance(VirtualPath virtualPath, String inputFile, HttpContext context) 。
         而通过http://test.cnblogs.com/default.aspx却能正常访问,服务器上与本机测试环境主要不同是服务器上程序是运行在IIS根目录,而本机是运行在虚拟目录中。然后,我在本机上将程序放在IIS根目录中运行,出现了同样的问题。
         于是,我用Reflector查看System.Web.UI.PageParser.GetCompiledPageInstance的代码,开始的代码是这样的:       

    IHttpHandler handler1; 
     
    if (context != null
          

                virtualPath 
    = context.Request.BaseDir.Combine(virtualPath); 
          }
     

         由于问题与访问路径有关,所以我格外关注上面的代码,上面的代码是对请求的虚拟路径进行处理。让我们看看context.Request.BaseDir的代码:

    internal VirtualPath BaseDir 
        

          
    get 
          

                
    if (this._baseVirtualDir == null
                

                      
    this._baseVirtualDir = this.FilePathObject.Parent; 
                }
     
                
    return this._baseVirtualDir; 
          }
     
        }
     

         FilePathObject.Parent是System.Web.VirtualPath的Parent属性,在Parent属性中开始有这样的代码:

    if (this.IsRoot)
                
    {
                      
    return null;
                }

         当以http://localhost/这样的根目录方式访问时,并且在IIS中设置中通配符映射(如果没有设置通配符映射,IIS会自动加上默认文档),这里IsRoot就是true,从IsRoot的代码可以看出:

    public bool IsRoot
    {
          
    get
          
    {
                
    return (this._virtualPath == "/");
          }

    }

           从上面的代码可以看出,当FilePathObject.Parent为null时,context.Request.BaseDir的值就是null,执行GetCompiledPageInstance中的context.Request.BaseDir.Combine(virtualPath); 就会引起“Object reference not set to an instance of an object”异常。 
         我觉得这是一个Bug,因为既然context.Request.BasDir有可能为null,就应该在context.Request.BaseDir.Combine(virtualPath)之前对context.Request.BasDir的值进行检查,对null值情况进行处理,或者在System.Web.VirtualPath的Parent属性中当IsRoot为true是直接返回“/”,而不是null,或者在System.Web.HttpRequest.BasDir中对_baseVirtualDir进行null检查,我觉得还是在HttpRequest中进行处理比较好,因为还有其他地方会调用System.Web.HttpRequest.BasDir,所以更准确地说应该是System.Web.HttpRequest的一个Bug。而在ASP.NET 1.1中就不存在这个bug,因为ASP.NET 1.1中System.Web.HttpRequest.BasDir不会返回null。 
         不知是否有其他方法避免这个问题,继续研究。

    ,-1,0,93,NULL,0 53353,343460,[ASP.NET 2.0]PageParser.GetCompiledPageInstance中的一个Bug及解决方法,2006-03-05 21:06:00,NULL,1,dudu,duyong@yz2pp.com,218.91.132.198,0,NULL,2006-03-06 23:49:00,NULL,

         最近在将博客园的程序迁移到ASP.NET 2.0,本来在本机虚拟目录中运行时可以正常访问首页,比如:http://localhost/blog。
         可到在服务器上测试时,访问地址:http://test.cnblogs.com,却出现“Object reference not set to an instance of an object”异常,异常产生于 System.Web.UI.PageParser.GetCompiledPageInstance(VirtualPath virtualPath, String inputFile, HttpContext context) 。
         而通过http://test.cnblogs.com/default.aspx却能正常访问,服务器上与本机测试环境主要不同是服务器上程序是运行在IIS根目录,而本机是运行在虚拟目录中。然后,我在本机上将程序放在IIS根目录中运行,出现了同样的问题。
         于是,我用Reflector查看System.Web.UI.PageParser.GetCompiledPageInstance的代码,开始的代码是这样的:       

    IHttpHandler handler1; 
     
    if (context != null
          

                virtualPath 
    = context.Request.BaseDir.Combine(virtualPath); 
          }
     

         由于问题与访问路径有关,所以我格外关注上面的代码,上面的代码是对请求的虚拟路径进行处理。让我们看看context.Request.BaseDir的代码:

    internal VirtualPath BaseDir 
        

          
    get 
          

                
    if (this._baseVirtualDir == null
                

                      
    this._baseVirtualDir = this.FilePathObject.Parent; 
                }
     
                
    return this._baseVirtualDir; 
          }
     
        }
     

         FilePathObject.Parent是System.Web.VirtualPath的Parent属性,在Parent属性中开始有这样的代码:

    if (this.IsRoot)
                
    {
                      
    return null;
                }

         当以http://localhost/这样的根目录方式访问时,并且在IIS中设置中通配符映射(如果没有设置通配符映射,IIS会自动加上默认文档),这里IsRoot就是true,从IsRoot的代码可以看出:

    public bool IsRoot
    {
          
    get
          
    {
                
    return (this._virtualPath == "/");
          }

    }

           从上面的代码可以看出,当FilePathObject.Parent为null时,context.Request.BaseDir的值就是null,执行GetCompiledPageInstance中的context.Request.BaseDir.Combine(virtualPath); 就会引起“Object reference not set to an instance of an object”异常。 
         我觉得这是一个Bug,因为既然context.Request.BasDir有可能为null,就应该在context.Request.BaseDir.Combine(virtualPath)之前对context.Request.BasDir的值进行检查,对null值情况进行处理,或者在System.Web.VirtualPath的Parent属性中当IsRoot为true是直接返回“/”,而不是null,或者在System.Web.HttpRequest.BasDir中对_baseVirtualDir进行null检查,我觉得还是在HttpRequest中进行处理比较好,因为还有其他地方会调用System.Web.HttpRequest.BasDir,所以更准确地说应该是System.Web.HttpRequest的一个Bug。而在ASP.NET 1.1中就不存在这个bug,因为ASP.NET 1.1中System.Web.HttpRequest.BasDir不会返回null。 
         不知是否有其他方法避免这个问题,继续研究。 
         [2006年3月6日修改]已经找到一种解决方法:在PageParser.GetCompiledPageInstance之前进行RewritePath处理,示例代码如下:

    if (url.ToLower().IndexOf(".aspx"< 0)
               {
                   
    if (!url.EndsWith("/"))
                   {
                       url 
    += "/";
                   }
                   url 
    += "default.aspx" ;
                   context.RewritePath(url);
                   
    return PageParser.GetCompiledPageInstance(url, pagepath, context);
               }
  • 相关阅读:
    Win Server 2008 R2 一键配置全环境 PHP5+MYSQL5+ZEND+PHPMYADMIN
    服务器加固,安全狗V4.0正式版 (Windows)
    Win server 2008 R2激活工具使用图文教程(SK Patch v1 R2 Final OEM)
    Laoy8 V4.0 营销插件
    OK3W发布插件
    流量精灵(P2P方式,刷真实流量)
    aspcms2发布插件
    今天写一篇技术文章,关于TemplateEngine的。
    全面分析新浪博客的登录过程
    网站克隆插件
  • 原文地址:https://www.cnblogs.com/dudu/p/344351.html
Copyright © 2020-2023  润新知