7

The property HttpContext.Current.Request.ApplicationPath represents the virtual directory in IIS or WebDev.WebServer.

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

This can be used in conjunction with VirtualPathUtility to make a path root relative :

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

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

In IIS6 and WebDev.WebServer the Request object is available in global.asax.cs, but IIS7 complains that it is 'not available in current context'. Therefore the second line of code above works but not in IIS7.

The problem is I need to access the virtual directroy name within global.asax.cs. I need it to construct some paths that are used in dynamically created CSS. Is there an alternative way to access this value?

Edit: This is the error you get in IIS 7 for calling HttpContext.Current.Request in global.asax.cs under Application_Start:

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

5 回答 5

14

终于找到了简单的答案!

 HttpRuntime.AppDomainAppVirtualPath

Application_Start 期间立即可用

这是/myapplication包含/前缀的形式。

于 2010-01-03T05:02:08.140 回答
0

Can you use ResolveUrl("~/images/cat.jpg") to build your path?

Edit: ResolveUrl is a method of Control, not just the Page class, so you can do it this way instead (bit ugly maybe):

System.Web.UI.Control c = new Control();
String s = c.ResolveUrl(@"~/images/cat.jpg");
于 2009-04-28T20:48:11.417 回答
0

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

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

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

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

    protected void Application_BeginRequest()
    {
        if (!_initialized)
        {
            lock (thisLock)
            {
                _initialized = true;
                GenerateCSSSprites();  
            }
        }
    }
于 2009-04-29T09:02:15.833 回答
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

于 2009-04-29T09:02:46.237 回答
0

嗯...我不知道 IIS7 的变化。我想知道在你有一个页面之前推迟这个操作是否会更简单。例如,您可以尝试在Application_BeginRequestor中放入“仅一次”的内容Session_Start

或者(完全未经测试)用于自退订挂钩:

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

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

    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;
    }
于 2009-04-29T08:29:36.440 回答