Могу ли я получить доступ к имени виртуального каталога на Global.asax.cs?
-
18-09-2019 - |
Вопрос
Недвижимость HttpContext.Current.Request.ApplicationPath
представляет виртуальный каталог в IIS или WebDev.Webserver.
HttpContext.Current.Request.ApplicationPath evaluates to "/virtualdirectory"
Это можно использовать в сочетании с VirtualPathUtility
Чтобы сделать root root относительно:
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 в приложении_start:
HttpException (0x80004005): Request is not available in this context]
System.Web.HttpContext.get_Request() +8789264
Решение
Наконец -то нашел простой ответ!
HttpRuntime.AppDomainAppVirtualPath
Доступно немедленно во время Application_start
Это форма /myapplication
в том числе /
префикс.
Другие советы
Можете ли вы использовать ResolveUrl ("~/images/cat.jpg") для создания вашего пути?
Редактировать: ResolveUrl - это метод управления, а не только класс страниц, так что вы можете сделать это таким образом (может быть, уродливо, может быть,):
System.Web.UI.Control c = new Control();
String s = c.ResolveUrl(@"~/images/cat.jpg");
Хммм ... Я не знал об изменении 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;
}
Хитрость заключается в том, чтобы сделать это только один раз (если несколько запросов появятся сразу); Возможно, статический CTTO? Например, я думаю, что это стреляет только один раз, и только тогда, когда есть страница, доступная в контексте:
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;
}
Это лучшее, что я придумал: Application_beginrequest (через Mark)
Я использую Asax так редко, что временно забыл, что вы получаете с ним разные события. До сих пор я создавал спрайты CSS в Application_Start
. Анкет Перемещение в BeartRequest было лучшее, что я мог придумать.
Один логический чек для каждого запроса незначительна, но было бы неплохо, если есть другой способ.
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
protected void Application_BeginRequest()
{
if (!_initialized)
{
lock (thisLock)
{
_initialized = true;
GenerateCSSSprites();
}
}
}
У меня тоже была эта проблема при переходе на IIS7, но я смог рефакторировать необходимость запроса. Это то, что этот парень также предлагает, и обеспечивает обходной путь, если вы не можете.