今天部署产品时,发现一个涉及到路径错误的bug,在开发环境下都OK,但是到了测试环境中却一直报错,经过一番排查,原来错误出在了HttpContext.Current.Server.MapPath这个方法上,之前就一直对这个方法怎样将虚拟路径转化为物理路径不甚了了,今天我忍无可忍,在网上仔细查找了资料,还亲自做了实验,终于弄明白了。在此分享出来,希望能帮助到同样有困惑的人,少走弯路。

虚拟路径中的那些特殊字符的含义

  • Server.MapPath(".")返回当前执行文件所在路径
  • Server.MapPath("..")返回当前执行文件所在路径的父路径
  • Server.MapPath("~") 返回应用程序的所在路径
  • Server.MapPath("/"),Server.MapPath("\\"),Server.MapPath(@"\") 返回网站所在路径
  • Server.MapPath("")Server.MapPath(null) 返回文件所在路径,和Server.MapPath(".")是一样的

众所周知我们在URL中的路径都是虚拟路径,最后都要被转化为网站所在服务器的物理路径,一般的路径都很好理解,对大家造成困扰的多是包含这些特殊字符的路径,他们在虚拟路径到物理路径的转化过程中有着特殊的含义。

举例说明

先在IIS中创建一个网站,网站域名为www.test.com,修改hosts文件将这个域名指向本机,网站目录为C:\inetpub\wwwroot\Test。在这个网站下添加应用程序Shop,目录为D:\Shop。在这个网站和应用程序中同时添加一个目录,取名main。

创建一个WebForm,这个WebForm输出上述所有特殊字符在运行时对应的路径,代码如下:

<% Output(".", "点号"); Output("..", "双点号"); Output("~","波浪号"); Output("/","正斜杠"); Output("\\", "反斜杠"); Output(@"\","反斜杠"); Output(null,"null"); Output(string.Empty, "string.Empty");

Output(@"\main", @"\main"); %> <script runat="server"> private void Output(string token, string tokenDisplayName) { try { string path = tokenDisplayName + " : " + HttpContext.Current.Server.MapPath(token); Response.Write(path + "<br/>"); } catch (Exception) { Response.Write(tokenDisplayName + " : 非法路径" + "<br/>"); } } </script>

我们把这个页面分别放到网站和应用程序的根目录以及main目录下,然后访问每个页面,输出如下:

 

结论

从上面的页面输出可以很好的验证文章开始处的说明,这里需要特别说明的几点是:

  • 在网站根目录下,访问Server.MapPath("..")会抛出异常,这说明网站中的所有访问不能超出网站所在的目录范围,这样的设计合情合理
  • 在URI中访问的路径都是虚拟路径,而不是物理路径,Shop这个应用程序的上一级目录不是其物理环境中的上一级目录,而是在IIS中其上级所在的目录,也就是网站所在的目录,因此在Shop这个应用程序中访问Server.MapPath("..")返回的C:\inetpub\wwwroot\Test
  • 不管是正斜杠还是反斜杠映射的都是网站根目录,之所以强调这一点是因为在网上查看资料的时候,见到如下的说法:在Shop应用程序的根目录下访问Server.MapPath(@"\main")返回的是D:\Shop\main目录,这个说法是绝对不正确的,特此提醒

解除.NET中虚拟路径的疑惑的更多相关文章

  1. Tomcat中虚拟路径

    默认情况下,Tomcat访问静态资源配置是这样的 <Context path="/project_name" docBase="d:\tomcat_statics& ...

  2. 关于web项目中的图片上传、并在前端显示问题(tomcat中配置文件上传虚拟路径)

    一.数据库存储 直接把图片的二进制码存到数据库,可参考blog:http://blog.csdn.net/hope2jiang/article/details/590733 直接存图片在mysql上面 ...

  3. 【转】关于web项目中的图片上传、并在前端显示问题(tomcat中配置文件上传虚拟路径)

    一.数据库存储 直接把图片的二进制码存到数据库,可参考blog:http://blog.csdn.net/hope2jiang/article/details/590733 直接存图片在mysql上面 ...

  4. myeclipse中tomcat配置虚拟路径,用于存储及上传图片

    由于双击tomcat后只出现了overview窗口,没有出现Models窗口,如下图所示,故eclipse中的方法不能用. 采用另一种方法 在自己的tomcat的安装目录下 ( 我安装目录的是 D:\ ...

  5. 如何在idea中设置Tomcat虚拟路径

    设置项目的根路径: 设置指定文件的在Tomcat中的虚拟路径: 代码: String fileName = MyFileUtil.getFileName(uploadFileName); File f ...

  6. IDEA 启动项目,tomcat中配置的虚拟路径无法使用

    有时候,使用idea启动项目,非动静分离项目,直接根据图片url地址显示图片,会发现图片无法显示,tomcat中配置的虚拟路径无法使用,这时候需要配置idea.选择路径,然后给与一个访问名就行了.

  7. 【IDEA】IDEA中配置tomcat虚拟路径的两种方法

    首先要确保使用的是本地的tomcat服务器,而不是maven插件. -------------------------第一种:使用IDEA工具自动配置(推荐这种)------------------- ...

  8. jsp网页在浏览器中不显示图片_eclipse环境下配置tomcat中jsp项目的虚拟路径

    遇到的问题是这种,在jsp网页中嵌入了本地的图片,由于会用到上传到服务器的图片,所以没有放到项目里面,而是把全部图片单独放到一个文件夹里,然后打算使用绝对路径把要显示的图片显示出来.比方是放在了E盘的 ...

  9. 【转】IDEA 中tomcat图片储存和访问虚拟路径

    1.idea 修改Tomcat的虚拟路径(第一种方法)修改配置文件有很多种,但是一直不成功;后来想还是idea的配置原因,这里tomcat虚拟路径只说一种; 修改Tomcat安装路径下server.x ...

随机推荐

  1. maven Java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

    如果你可以确认你的maven Dependencies中已经导入了如下的jar包,那么你就要检查下Deployment Assembly 选中项目 alt+enter,然后查看maven依赖有没有被添 ...

  2. Swift下CoreData的使用

    我之前的随笔中有写过一些iOS持久化存储的方法,包含了sqlite.解归档.沙盒存放等等.这些方式中,能够大规模存储,并保持性能的只有使用sqlite了.而这里将记录下Cocoa自身继承的数据库的存储 ...

  3. 改变浏览器中默认的ctrl+s方法

    在一般的情况下,我们在浏览网页的时候按下ctrl+s,浏览器会弹出一个保存网页的框. 但是在一些特定的网页中,我们希望ctrl+s不是弹出默认的保存窗口,而是进行一下别的操作. 比如在我们使用简书的时 ...

  4. No USB devices or running emulators detected”

    每次重装系统之后,安装andorid studio后,使用真机调试代码,就会出现"No USB devices or running emulators detected"的错误, ...

  5. 浏览器加载js文件顺序

    在默认情况下,下载和执行js都会阻塞页面的渲染,当然现在浏览器支持并行下载,但仍然会阻塞图片等的下载和渲染,所以通常建议把js文件放body底.对于执行顺序,不管是外部js还是内部,只要 遇到< ...

  6. React为啥很多类里的标签上事件处理函数要用bind(this)

    render() { return ( <div> <p onClick={this.clickHandler.bind(this)}>vz</p> </di ...

  7. JAVA从本机获取IP地址

    JAVA从本机获取IP地址 论述: 此篇博客是在工作的时候,需要获得当前网络下面正确的ip地址,在网上查阅很多博客,网上一个比较普遍的说法是通过InetAddress.getLocalHost().g ...

  8. Linux调试工具

    1. 使用printf调试 #ifdef DEBUG Printf(“valriable x has value = %d\n”, x) #endif 然后在编译选项中加入-DDEBUG 更复杂的调试 ...

  9. 优秀开源项目之四:CrashRptProbe,查询程序奔溃的利器

    1.背景: 在开发人员进行项目开发和调试代码时,有一个非常困扰的问题,就是程序在调试运行过程中会莫名其妙地异常退出.由于导致异常退出的问题非常多,因此在面对这种无任何提示的异常退出时,开发人员会非常无 ...

  10. MIS的趋势必定是围绕机器取代人手,分工越来越细(小餐厅都支持微信自助点餐,结账时就打个折,相当于省了1、2个人手,SQL发明以后,程序员的工作更多了)

    最后,我还想简略的谈谈MIS及MIS快速开发工具的未来. MIS的趋势必定是围绕机器取代人手,分工越来越细.比如:现在有些小型的咖啡厅里的财务子系统就简单到不需要使用者有会计知识,相当于省了会计人手: ...