定时发布任务,在global.asax中获取文件的物理路径的方法
如果要把一个相对路径或者虚拟路径映射道服务器的物理路径,通常会使用Server.MapPath()函数,比如将根目录下的html目录映射为物理路径:Server.MapPath("html"),可以返回形如"E:\www\htm\"的字符串。通常情况下我们都不会遇到什么问题。
新手常常会发现在诸如自己的类文件中无法使用Server.MapPath(),这是由于没有引入相应的命名空间,只要把全名写出来,即用System.Web.HttpContext.Current.Server.MapPath(),问题就迎刃而解了。
最近老板让我做一个可以定时发布文章的CMS,他的意思是做一个网站,但是他不想管理这个网站,只是想一个月来管一次,但是又要保持网站每天更新(真是够懒的,想得还真美)。就是说网站每天会自己更新,多么好的网站啊。这里面我首先想到的是使用定时器,但是web程序是相当被动的,只有当用户请求时,它才会工作,这个问题困扰了我很久。
不过还好,几经周折才找到可以在global.asax中实现这种功能,该文件是一个网站应用程序可选的全局文件,定义了有很多事件,其中的Application_Start()函数可以在整个网站应用程序启动时被触发,因此我就在这里触发一个定时器,通过这个定时器不断触发我的定时发发布函数。
定时发布功能我做到了一个类里面,类里面用到了Server.MapPath(),但是这个类真的好奇怪,我在其他地方调用时都可以工作正常,但是在global.asax中调用是老是在MapPath()一行提示“未将对象引用设置到对象的实例”的错误。弄了N久也没有结果,郁闷至极,上网搜了N久,又到百度知道中花了200分悬赏也没有得到答案,千篇一律的给出使用Server.MapPath(),而这是根本不行的。
经过钻研,发现原来在global.axax中并没有请求上下文,因此System.Web.HttpContext是Null,更不要说使用其成员了,所以这条路是走不通了。难道就没有其他获取物理路径的方法了吗?又是一番周折,我发现了HttpRuntime这个神奇的类,它并不需要请求上下文,而它恰好有一个熟悉AppDomainAppPath,给出了当前应用程序的根目录,有了这个东西,加上我已知的虚拟路径不久得到了我相应的文件的物理路径了吗。试了一下,果然实现了,呵呵,一个困难又被我解决了。
总结一下:如果没有请求上下文System.Web.HttpContext就是空值,自然不能实现任何功能。如果想在这种情况下得到物理路径可以使用HttpRuntime.AppDomainAppPath获取应用程序的物理根目录,有了这个根目录就可以获取所有文件的物理路径了。