Могу ли я получить доступ к имени виртуального каталога в global.asax.cs?

Недвижимость 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, но IIS7 жалуется, что он "недоступен в текущем контексте". Поэтому вторая строка кода выше работает, но не в IIS7.

Проблема в том, что мне нужно получить доступ к виртуальному имени директрой global.asax.cs, Мне нужно, чтобы построить несколько путей, которые используются в динамически создаваемых CSS. Есть ли альтернативный способ доступа к этому значению?

Изменить: это ошибка, которую вы получаете в IIS 7 для вызова HttpContext.Current.Request в global.asax.cs под Application_Start:

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

5 ответов

Решение

Наконец-то нашел простой ответ!

 HttpRuntime.AppDomainAppVirtualPath

Доступно сразу во время Application_Start

Это имеет форму /myapplication в том числе / префикс.

Можете ли вы использовать ResolveUrl("~/images/cat.jpg"), чтобы построить свой путь?

Редактировать: ResolveUrl - это метод Control, а не просто класс Page, поэтому вы можете сделать это таким образом (возможно, немного некрасиво):

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

Это лучшее, что я придумал: 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();  
            }
        }
    }

Хммм... я не знал об изменении IIS7. Интересно, не будет ли проще отложить эту операцию, пока у вас не появится страница? Например, вы можете попробовать поместить что-то "только один раз" в Application_BeginRequest или же Session_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;
    }

У меня тоже была эта проблема при переходе на IIS7, но я смог реорганизовать необходимость запроса. Это то, что этот парень также предлагает и предлагает обходной путь, если вы не можете.

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

Другие вопросы по тегам