我可以访问global.asax.cs中的虚拟目录名吗?

时间:2009-04-28 20:42:13

标签: asp.net requestcontext

属性HttpContext.Current.Request.ApplicationPath表示IIS或WebDev.WebServer中的虚拟目录。

 HttpContext.Current.Request.ApplicationPath evaluates to "/virtualdirectory"

这可以与VirtualPathUtility结合使用,使路径根相对:

 VirtualPathUtility.ToAbsolute("~/images/cat.jpg",
                               HttpContext.Current.Request.ApplicationPath)

 // (this evaluates to "/virtualdirectory/images/cat.jpg")

在IIS6和WebDev.WebServer中,global.asax.cs中的Request对象 可用,但IIS7抱怨它“在当前上下文中不可用”。因此,上面的第二行代码可以工作,但不能在IIS7中工作。

问题是我需要访问global.asax.cs中的虚拟directroy名称。我需要它来构建一些在动态创建的CSS中使用的路径。有没有其他方法可以访问此值?

编辑:这是您在IIS 7中调用Application_Start下的global.asax.cs中调用HttpContext.Current.Request时出现的错误:

 HttpException (0x80004005): Request is not available in this context]
    System.Web.HttpContext.get_Request() +8789264

5 个答案:

答案 0 :(得分:14)

终于找到了简单的答案!

 HttpRuntime.AppDomainAppVirtualPath

在Application_Start期间立即可用

此格式为/myapplication,包含/前缀。

答案 1 :(得分:0)

您可以使用ResolveUrl(“〜/ images / cat.jpg”)来构建路径吗?

编辑:ResolveUrl是一种控制方法,而不仅仅是Page类,所以你可以这样做(有点丑陋):

System.Web.UI.Control c = new Control();
String s = c.ResolveUrl(@"~/images/cat.jpg");

答案 2 :(得分:0)

嗯......我不知道IIS7的变化。我想知道在你拥有页面之前推迟这个操作是不是更简单。例如,您可以尝试在Application_BeginRequestSession_Start

中添加“仅一次”内容

或者(完全未经测试)自我取消订阅的钩子:

    public override void Init() {
        base.Init();
        EventHandler handler = null;
        handler = delegate {
            // do stuff, once only
            this.BeginRequest -= handler;
        };
        this.BeginRequest += handler;
    }

诀窍是只做一次(如果多次请求一次到达);也许是一个静态的ctor?例如,我认为这只会触发一次,并且只有在上下文中有可用页面时才会触发:

    static class DelayedLoader {
        static DelayedLoader() {
            string s = VirtualPathUtility.ToAbsolute("~/images/cat.jpg",
                           HttpContext.Current.Request.ApplicationPath);
        }
        [MethodImpl(MethodImplOptions.NoInlining)]
        public static void Init() { }
    }
    public override void Init() {
        base.Init();
        EventHandler handler = null;
        handler = delegate {
            DelayedLoader.Init();
            this.BeginRequest -= handler;
        };
        this.BeginRequest += handler;
    }

答案 3 :(得分:0)

这是我提出的最好的:Application_BeginRequest(通过标记)

我很少使用asax,因为我暂时忘记了你得到了不同的事件。到目前为止,我一直在Application_Start创建CSS精灵。把它移到BeginRequest是我能想到的最好的。

每个请求的一个布尔检查可以忽略不计,但如果有不同的方法则会很好。

  protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }

    protected void Application_BeginRequest()
    {
        if (!_initialized)
        {
            lock (thisLock)
            {
                _initialized = true;
                GenerateCSSSprites();  
            }
        }
    }

答案 4 :(得分:0)

切换到IIS7时我也遇到了这个问题,但我能够重构对Request的需求。如果你不能,这个人也会建议并提供一个解决方法。

http://mvolo.com/blogs/serverside/archive/2007/11/10/Integrated-mode-Request-is-not-available-in-this-context-in-Application_5F00_Start.aspx